diff --git a/jode/jode/decompiler/CodeAnalyzer.java b/jode/jode/decompiler/CodeAnalyzer.java index 4aff8a9..7111b39 100644 --- a/jode/jode/decompiler/CodeAnalyzer.java +++ b/jode/jode/decompiler/CodeAnalyzer.java @@ -19,13 +19,11 @@ package jode.decompiler; import jode.*; -import jode.bytecode.ClassInfo; -import jode.bytecode.ConstantPool; -import jode.bytecode.AttributeInfo; -import jode.bytecode.CodeInfo; +import jode.bytecode.*; import jode.flow.FlowBlock; import jode.flow.TransformExceptionHandlers; +import java.util.BitSet; import java.util.Stack; import java.util.Vector; import java.util.Enumeration; @@ -36,7 +34,7 @@ import java.io.IOException; public class CodeAnalyzer implements Analyzer { FlowBlock methodHeader; - CodeInfo code; + BytecodeInfo code; MethodAnalyzer method; public JodeEnvironment env; @@ -50,20 +48,30 @@ public class CodeAnalyzer implements Analyzer { */ public MethodAnalyzer getMethod() {return method;} - public CodeAnalyzer(MethodAnalyzer ma, CodeInfo bc, JodeEnvironment e) - throws ClassFormatError + public CodeAnalyzer(MethodAnalyzer ma, + AttributeInfo codeattr, JodeEnvironment e) { - code = bc; method = ma; env = e; + DataInputStream stream = new DataInputStream + (new ByteArrayInputStream(codeattr.getContents())); + ConstantPool cpool = ma.classAnalyzer.getConstantPool(); + code = new BytecodeInfo(); + try { + code.read(cpool, stream); + } catch (IOException ex) { + ex.printStackTrace(Decompiler.err); + code = null; + return; + } + if (Decompiler.useLVT) { AttributeInfo attr = code.findAttribute("LocalVariableTable"); if (attr != null) { if (Decompiler.showLVT) Decompiler.err.println("Method: "+ma.getName()); - lvt = new LocalVariableTable(bc.getMaxLocals(), - method.classAnalyzer, attr); + lvt = new LocalVariableTable(code.getMaxLocals(), cpool, attr); } } @@ -73,7 +81,7 @@ public class CodeAnalyzer implements Analyzer { param[i] = getLocalInfo(0, i); } - public CodeInfo getCodeInfo() { + public BytecodeInfo getBytecodeInfo() { return code; } @@ -81,51 +89,38 @@ public class CodeAnalyzer implements Analyzer { return methodHeader; } - private final static int SEQUENTIAL = 1; - private final static int PREDECESSORS = 2; - /** - * @param code The code array. - * @param handlers The exception handlers. - */ - void readCode(byte[] code, int[] handlers) - throws ClassFormatError - { - ConstantPool cpool = method.classAnalyzer.getConstantPool(); - byte[] flags = new byte[code.length]; - int[] lengths = new int[code.length]; - try { - DataInputStream stream = - new DataInputStream(new ByteArrayInputStream(code)); - for (int addr = 0; addr < code.length; ) { - int[] succs = Opcodes.getSizeAndSuccs(addr, stream); - if (succs.length == 2 - && succs[1] == addr + succs[0]) - flags[addr] |= SEQUENTIAL; - lengths[addr] = succs[0]; - addr += succs[0]; - for (int i=1; i mark) { + if (jode.Decompiler.isVerbose && instr.addr > mark) { Decompiler.err.print('.'); mark += 1000; } - if (lastBlock != null && flags[addr] == SEQUENTIAL) { - - lastBlock.doSequentialT1(block, lengths[addr]); + if (lastSequential && instr.tmpInfo == null + /* Only merge with previous block, if this is sequential, + * too. + * Why? doSequentialT1 does only handle sequential blocks. + */ + && !instr.alwaysJumps && instr.succs == null) { + + lastBlock.doSequentialT1(block, instr.length); } else { - - instr[addr] = new FlowBlock(this, addr, - lengths[addr], block); - lastBlock = ((flags[addr] & SEQUENTIAL) == 0) - ? null : instr[addr]; + if (instr.tmpInfo == null) + instr.tmpInfo = new FlowBlock + (this, instr.addr, instr.length); + FlowBlock flowBlock = (FlowBlock) instr.tmpInfo; + flowBlock.setBlock(block); + + if (lastBlock != null) + lastBlock.setNextByAddr(flowBlock); + + instr.tmpInfo = lastBlock = flowBlock; + lastSequential = !instr.alwaysJumps && instr.succs == null; } - addr += lengths[addr]; } - for (int addr=0; addr