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. 25
      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> 2001-08-14 Jochen Hoenicke <jochen@gnu.org>
* build.xml: test is default. * build.xml: test is default.

@ -39,6 +39,7 @@ class BasicBlockReader implements Opcodes {
static final int IS_REACHABLE = 2; static final int IS_REACHABLE = 2;
static final int IS_FORWARD = 4; static final int IS_FORWARD = 4;
static final int IS_CATCHER = 8; static final int IS_CATCHER = 8;
static final int IS_NULL = 16;
private class InstrInfo { private class InstrInfo {
Instruction instr; Instruction instr;
@ -97,8 +98,20 @@ class BasicBlockReader implements Opcodes {
&& (info.instr.getOpcode() == opc_goto && (info.instr.getOpcode() == opc_goto
|| (info.instr.getOpcode() == opc_return || (info.instr.getOpcode() == opc_return
&& info.stack == 0))) { && info.stack == 0))) {
/* This is a forward block. /* This is a forward block. We need to check for loops,
* though.
*/ */
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; info.flags |= IS_FORWARD;
} else { } else {
// Check for reachable exception handlers // Check for reachable exception handlers
@ -240,11 +253,11 @@ class BasicBlockReader implements Opcodes {
private void convertBlock(int firstAddr, int count) { private void convertBlock(int firstAddr, int count) {
Instruction[] instrs = new Instruction[count]; Instruction[] instrs = new Instruction[count];
InstrInfo info = infos[firstAddr]; InstrInfo info = infos[firstAddr];
int blockNr = info.blockNr; int blockNr = info.blockNr;
instrs[0] = info.instr;
for (int i=1; i < count; i++) { for (int i = 0; i < count; i++) {
if (i > 0)
info = infos[info.nextAddr]; info = infos[info.nextAddr];
instrs[i] = info.instr; instrs[i] = info.instr;
} }
@ -292,9 +305,13 @@ class BasicBlockReader implements Opcodes {
start = -1; start = -1;
} }
if ((info.flags & (IS_REACHABLE | IS_FORWARD)) == IS_REACHABLE) { if ((info.flags & (IS_REACHABLE | IS_FORWARD)) == IS_REACHABLE) {
if ((info.flags & IS_NULL) != 0) {
convertBlock(i, 0);
} else {
start = i; start = i;
count = 0; count = 0;
} }
}
if (start != -1) if (start != -1)
count++; count++;
} }

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

Loading…
Cancel
Save