From c11b2426df5b150684d9a672801effa646be8723 Mon Sep 17 00:00:00 2001 From: hoenicke Date: Fri, 15 Feb 2002 15:22:50 +0000 Subject: [PATCH] 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 --- jode/ChangeLog | 11 ++++++ .../sf/jode/bytecode/BasicBlockReader.java | 35 ++++++++++++++----- .../sf/jode/decompiler/MethodAnalyzer.java | 10 +++--- 3 files changed, 42 insertions(+), 14 deletions(-) diff --git a/jode/ChangeLog b/jode/ChangeLog index 8a2d1d4..aecd9a1 100644 --- a/jode/ChangeLog +++ b/jode/ChangeLog @@ -1,3 +1,14 @@ +2002-02-15 Jochen Hoenicke + + * 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 * build.xml: test is default. diff --git a/jode/src/net/sf/jode/bytecode/BasicBlockReader.java b/jode/src/net/sf/jode/bytecode/BasicBlockReader.java index b388658..da2a49a 100644 --- a/jode/src/net/sf/jode/bytecode/BasicBlockReader.java +++ b/jode/src/net/sf/jode/bytecode/BasicBlockReader.java @@ -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++; diff --git a/jode/src/net/sf/jode/decompiler/MethodAnalyzer.java b/jode/src/net/sf/jode/decompiler/MethodAnalyzer.java index 6c593a7..91c8148 100644 --- a/jode/src/net/sf/jode/decompiler/MethodAnalyzer.java +++ b/jode/src/net/sf/jode/decompiler/MethodAnalyzer.java @@ -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 };