*** empty log message ***

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@35 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 27 years ago
parent 294026c0f8
commit 674d865943
  1. 57
      jode/jode/decompiler/CodeAnalyzer.java
  2. 38
      jode/jode/decompiler/MethodAnalyzer.java
  3. 143
      jode/jode/flow/FlowBlock.java
  4. 107
      jode/jode/flow/RawTryCatchBlock.java

@ -22,6 +22,9 @@ import sun.tools.java.*;
import java.util.Stack; import java.util.Stack;
import java.io.*; import java.io.*;
import jode.flow.FlowBlock; import jode.flow.FlowBlock;
import jode.flow.Jump;
import jode.flow.StructuredBlock;
import jode.flow.RawTryCatchBlock;
public class CodeAnalyzer implements Analyzer, Constants { public class CodeAnalyzer implements Analyzer, Constants {
@ -31,6 +34,7 @@ public class CodeAnalyzer implements Analyzer, Constants {
MethodAnalyzer method; MethodAnalyzer method;
public JodeEnvironment env; public JodeEnvironment env;
jode.flow.VariableSet param;
LocalVariableTable lvt; LocalVariableTable lvt;
/** /**
@ -73,26 +77,43 @@ public class CodeAnalyzer implements Analyzer, Constants {
} catch (IOException ex) { } catch (IOException ex) {
throw new ClassFormatError(ex.toString()); throw new ClassFormatError(ex.toString());
} }
BinaryExceptionHandler[] handlers = bincode.getExceptionHandlers();
for (int addr=0; addr<instr.length; ) { for (int addr=0; addr<instr.length; ) {
instr[addr].resolveJumps(instr); instr[addr].resolveJumps(instr);
addr = instr[addr].getNextAddr(); addr = instr[addr].getNextAddr();
} }
methodHeader = instr[0]; methodHeader = instr[0];
methodHeader.makeStartBlock(); methodHeader.makeStartBlock();
/* XXX do something with handlers */
}
/* BinaryExceptionHandler[] handlers = bincode.getExceptionHandlers();
tryAddrs.put(new Integer(handler.startPC), handler); for (int i=0; i<handlers.length; i++) {
references[handler.startPC]++; StructuredBlock tryBlock = instr[handlers[i].startPC].getBlock();
catchAddrs.put(new Integer(handler.handlerPC), handler); while (tryBlock instanceof RawTryCatchBlock
references[handler.handlerPC]++; && (((RawTryCatchBlock) tryBlock).getCatchAddr()
*/ > handlers[i].handlerPC)) {
tryBlock = ((RawTryCatchBlock)tryBlock).getTryBlock();
}
Type type =
(handlers[i].exceptionClass != null)?
handlers[i].exceptionClass.getType() : null;
new RawTryCatchBlock(type, tryBlock,
new Jump(instr[handlers[i].endPC]),
new Jump(instr[handlers[i].handlerPC]));
}
int paramCount = method.mdef.getType().getArgumentTypes().length
+ (method.mdef.isStatic() ? 0 : 1);
param = new jode.flow.VariableSet();
for (int i=0; i<paramCount; i++)
param.addElement(getLocalInfo(-1, i));
}
public void dumpSource(TabbedPrintWriter writer) public void dumpSource(TabbedPrintWriter writer)
throws java.io.IOException throws java.io.IOException
{ {
methodHeader.makeDeclaration(param);
methodHeader.dumpSource(writer); methodHeader.dumpSource(writer);
} }
@ -109,18 +130,22 @@ public class CodeAnalyzer implements Analyzer, Constants {
if (lvt != null) if (lvt != null)
return lvt.getLocal(slot).getInfo(addr); return lvt.getLocal(slot).getInfo(addr);
else else
return new LocalInfo(slot); /*XXX*/ return new LocalInfo(slot);
}
public LocalInfo getParamInfo(int slot) {
return (LocalInfo) param.elementAt(slot);
} }
static jode.flow.Transformation[] exprTrafos = { static jode.flow.Transformation[] exprTrafos = {
new jode.flow.RemoveEmpty(), new jode.flow.RemoveEmpty(),
// new CombineCatchLocal(), // new CombineCatchLocal(),
new jode.flow.CreateExpression(), new jode.flow.CreateExpression(),
// new CreatePostIncExpression(), new jode.flow.CreatePostIncExpression(),
// new CreateAssignExpression(), new jode.flow.CreateAssignExpression(),
new jode.flow.CreateNewConstructor(), new jode.flow.CreateNewConstructor(),
new jode.flow.CombineIfGotoExpressions(), new jode.flow.CombineIfGotoExpressions(),
// new CreateIfThenElseOperator(), new jode.flow.CreateIfThenElseOperator(),
// new CreateConstantArray(), // new CreateConstantArray(),
new jode.flow.SimplifyExpression() new jode.flow.SimplifyExpression()
}; };
@ -176,14 +201,16 @@ public class CodeAnalyzer implements Analyzer, Constants {
* *
* Otherwise flow transformation didn't succeeded. * Otherwise flow transformation didn't succeeded.
*/ */
System.err.println("breaking analyzation; flow: " // System.err.println("breaking analyzation; flow: "
+ flow.getLabel()); // + flow.getLabel());
while (!todo.isEmpty()) { while (!todo.isEmpty()) {
System.err.println("on Stack: " System.err.println("on Stack: "
+ ((FlowBlock)todo.pop()).getLabel()); + ((FlowBlock)todo.pop()).getLabel());
} }
break analyzation; break analyzation;
} }
if (Decompiler.isVerbose)
System.err.print(".");
} }
} }

@ -50,29 +50,36 @@ public class MethodAnalyzer implements Analyzer, Constants {
} }
public void analyze() public void analyze()
throws ClassFormatError throws ClassFormatError
{ {
if (code == null) if (code == null)
return; return;
// if (Decompiler.isVerbose)
// System.err.print(mdef.getName().toString()+": "); int offset = 0;
// lva.createLocalInfo(code); if (!mdef.isStatic()) {
// code.analyze(); LocalInfo clazz = code.getParamInfo(0);
// if (Decompiler.isVerbose) clazz.setType(mdef.getClassDefinition().getType());
// System.err.println(""); clazz.setName(Constants.idThis);
offset++;
}
Type[] paramTypes = mdef.getType().getArgumentTypes();
for (int i=0; i< paramTypes.length; i++)
code.getParamInfo(offset+i).setType(paramTypes[i]);
// We do the code.analyze() in dumpSource, to get
// immediate output.
} }
public void dumpSource(TabbedPrintWriter writer) public void dumpSource(TabbedPrintWriter writer)
throws java.io.IOException throws java.io.IOException
{ {
if (code != null) { if (code != null) {
if (Decompiler.isVerbose) if (Decompiler.isVerbose)
System.err.print(mdef.getName().toString()+": "); System.err.print(mdef.getName().toString()+": ");
// lva.createLocalInfo(code); code.analyze();
code.analyze(); if (Decompiler.isVerbose)
if (Decompiler.isVerbose) System.err.println("");
System.err.println(""); }
}
writer.println(""); writer.println("");
String modif = Modifier.toString(mdef.getModifiers()); String modif = Modifier.toString(mdef.getModifiers());
@ -97,7 +104,7 @@ public class MethodAnalyzer implements Analyzer, Constants {
env.getTypeString(paramTypes[i]): env.getTypeString(paramTypes[i]):
env.getTypeString env.getTypeString
(paramTypes[i], (paramTypes[i],
code.getLocalInfo(-1, i+offset).getName())); code.getParamInfo(i+offset).getName()));
} }
writer.print(")"); writer.print(")");
} }
@ -116,7 +123,6 @@ public class MethodAnalyzer implements Analyzer, Constants {
if (code != null) { if (code != null) {
writer.println(" {"); writer.println(" {");
writer.tab(); writer.tab();
// lva.dumpSource(writer);
code.dumpSource(writer); code.dumpSource(writer);
writer.untab(); writer.untab();
writer.println("}"); writer.println("}");

@ -105,6 +105,34 @@ public class FlowBlock {
return addr+length; return addr+length;
} }
/**
* Create a Catch- resp. FinallyBlock (maybe even SynchronizedBlock)
* @param sequBlock a SequentialBlock whose first sub block is a
* RawTryCatchBlock.
*/
public StructuredBlock createCatchBlock(SequentialBlock sequBlock) {
RawTryCatchBlock tryBlock = (RawTryCatchBlock) sequBlock.subBlocks[0];
StructuredBlock catchBlock = sequBlock.subBlocks[1];
if (tryBlock.type != null) {
/*XXX crude hack */
catchBlock.replace(sequBlock, tryBlock);
CatchBlock newBlock = new CatchBlock(tryBlock);
newBlock.replace(catchBlock, catchBlock);
newBlock.setCatchBlock(catchBlock);
if (sequBlock.jump != null) {
if (newBlock.catchBlock.jump == null)
newBlock.catchBlock.moveJump(sequBlock);
else
sequBlock.removeJump();
}
return newBlock;
} else {
/* XXX implement finally */
return sequBlock;
}
}
/** /**
* This method optimizes the jumps to successor. * This method optimizes the jumps to successor.
* Returns the new appendBlock, it may have changed. * Returns the new appendBlock, it may have changed.
@ -238,9 +266,22 @@ public class FlowBlock {
SequentialBlock sequBlock = new SequentialBlock(); SequentialBlock sequBlock = new SequentialBlock();
StructuredBlock prevBlock = jump.prev; StructuredBlock prevBlock = jump.prev;
prevBlock.removeJump(); prevBlock.removeJump();
sequBlock.replace(prevBlock, prevBlock); if (prevBlock instanceof EmptyBlock) {
sequBlock.setFirst(prevBlock); if (prevBlock.outer instanceof ConditionalBlock) {
sequBlock.setSecond(new ReturnBlock()); IfThenElseBlock ifBlock =
new IfThenElseBlock
(((ConditionalBlock)prevBlock.outer).
getInstruction());
ifBlock.replace(prevBlock.outer, prevBlock);
ifBlock.moveJump(prevBlock.outer);
ifBlock.setThenBlock(prevBlock);
}
new ReturnBlock().replace(prevBlock, null);
} else {
sequBlock.replace(prevBlock, prevBlock);
sequBlock.setFirst(prevBlock);
sequBlock.setSecond(new ReturnBlock());
}
continue next_jump; continue next_jump;
} }
@ -331,12 +372,27 @@ public class FlowBlock {
else else
prevBlock.removeJump(); prevBlock.removeJump();
sequBlock.replace(prevBlock, prevBlock); if (prevBlock instanceof EmptyBlock) {
sequBlock.setFirst(prevBlock); if (prevBlock.outer instanceof ConditionalBlock) {
sequBlock.setSecond IfThenElseBlock ifBlock =
(new BreakBlock((BreakableBlock) surrounder, new IfThenElseBlock
breaklevel > 1)); (((ConditionalBlock)prevBlock.outer)
continue next_jump; .getInstruction());
ifBlock.replace(prevBlock.outer, prevBlock);
ifBlock.moveJump(prevBlock.outer);
ifBlock.setThenBlock(prevBlock);
}
new BreakBlock((BreakableBlock) surrounder,
breaklevel >1
).replace(prevBlock, null);
} else {
sequBlock.replace(prevBlock, prevBlock);
sequBlock.setFirst(prevBlock);
sequBlock.setSecond
(new BreakBlock((BreakableBlock) surrounder,
breaklevel > 1));
}
continue same_jump;
} }
} }
} }
@ -373,8 +429,8 @@ public class FlowBlock {
intersectOut = intersectOut.intersect(jump.out); intersectOut = intersectOut.intersect(jump.out);
} }
System.err.println("UpdateInOut: allOuts : "+allOuts); // System.err.println("UpdateInOut: allOuts : "+allOuts);
System.err.println(" intersectOut: "+intersectOut); // System.err.println(" intersectOut: "+intersectOut);
/* Merge the locals used in successing block with those written /* Merge the locals used in successing block with those written
* by this blocks * by this blocks
@ -382,7 +438,7 @@ public class FlowBlock {
VariableSet defineHere = successor.in.merge(allOuts); VariableSet defineHere = successor.in.merge(allOuts);
defineHere.subtractExact(in); defineHere.subtractExact(in);
System.err.println(" defineHere : "+defineHere); // System.err.println(" defineHere : "+defineHere);
if (t1Transformation) { if (t1Transformation) {
/* Now update in and out set of successing block */ /* Now update in and out set of successing block */
successor.in.subtract(intersectOut); successor.in.subtract(intersectOut);
@ -394,9 +450,9 @@ public class FlowBlock {
jump.out.add(intersectOut); jump.out.add(intersectOut);
} }
} }
System.err.println(" successor.in: "+successor.in); // System.err.println(" successor.in: "+successor.in);
in.union(successor.in); in.union(successor.in);
System.err.println(" in : "+in); // System.err.println(" in : "+in);
/* XXX - do something with defineHere */ /* XXX - do something with defineHere */
return defineHere; /*XXX - correct???*/ return defineHere; /*XXX - correct???*/
} }
@ -484,7 +540,7 @@ public class FlowBlock {
if (prevSucc != null && fb.addr <= prevSucc.addr) if (prevSucc != null && fb.addr <= prevSucc.addr)
continue; continue;
if (succ == null || fb.addr < succ.addr) { if (succ == null || fb.addr < succ.addr) {
System.err.println("trying "+fb.getLabel()); // System.err.println("trying "+fb.getLabel());
succ = fb; succ = fb;
} }
} }
@ -546,13 +602,14 @@ public class FlowBlock {
return false; return false;
try{ try{
System.err.println("doing T1 analysis on: "+getLabel()); // System.err.println("doing T1 analysis on: "+getLabel());
System.err.println("***in: "+in); // System.err.println("***in: "+in);
checkConsistent(); checkConsistent();
System.err.println("and "+succ.getLabel()); // System.err.println("and "+succ.getLabel());
System.err.println("+++in: "+succ.in); // System.err.println("+++in: "+succ.in);
succ.checkConsistent(); succ.checkConsistent();
} catch (RuntimeException ex) { } catch (RuntimeException ex) {
ex.printStackTrace();
try { try {
jode.TabbedPrintWriter writer = jode.TabbedPrintWriter writer =
new jode.TabbedPrintWriter(System.err, " "); new jode.TabbedPrintWriter(System.err, " ");
@ -573,8 +630,19 @@ public class FlowBlock {
if (jump == null || jump.destination != succ) if (jump == null || jump.destination != succ)
continue; continue;
while (!appendBlock.contains(jump.prev)) while (!appendBlock.contains(jump.prev)) {
appendBlock = appendBlock.outer; appendBlock = appendBlock.outer;
if (appendBlock instanceof SequentialBlock
&& appendBlock.getSubBlocks()[0]
instanceof RawTryCatchBlock) {
/* We leave the catch block of a raw-try-catch-block.
* We shall now create the Catch- resp. FinallyBlock.
*/
appendBlock =
createCatchBlock((SequentialBlock)appendBlock);
}
}
/* appendBlock can't be null now, because the /* appendBlock can't be null now, because the
* outermost block contains every structured block. * outermost block contains every structured block.
*/ */
@ -650,9 +718,10 @@ public class FlowBlock {
} }
try { try {
System.err.println("before optimizeJump: "+getLabel()); // System.err.println("before optimizeJump: "+getLabel());
checkConsistent(); checkConsistent();
} catch (RuntimeException ex) { } catch (RuntimeException ex) {
ex.printStackTrace();
try { try {
jode.TabbedPrintWriter writer = jode.TabbedPrintWriter writer =
new jode.TabbedPrintWriter(System.err, " "); new jode.TabbedPrintWriter(System.err, " ");
@ -668,9 +737,10 @@ public class FlowBlock {
appendBlock = optimizeJumps(succ, appendBlock); appendBlock = optimizeJumps(succ, appendBlock);
try { try {
System.err.println("after optimizeJump: "+getLabel()); // System.err.println("after optimizeJump: "+getLabel());
checkConsistent(); checkConsistent();
} catch (RuntimeException ex) { } catch (RuntimeException ex) {
ex.printStackTrace();
try { try {
jode.TabbedPrintWriter writer = jode.TabbedPrintWriter writer =
new jode.TabbedPrintWriter(System.err, " "); new jode.TabbedPrintWriter(System.err, " ");
@ -703,6 +773,7 @@ public class FlowBlock {
LoopBlock.FALSE); LoopBlock.FALSE);
int breaklevel = 1; int breaklevel = 1;
Jump debug=jump;
for (StructuredBlock surrounder = jump.prev.outer; for (StructuredBlock surrounder = jump.prev.outer;
surrounder != appendBlock.outer; surrounder != appendBlock.outer;
surrounder = surrounder.outer) { surrounder = surrounder.outer) {
@ -745,10 +816,11 @@ public class FlowBlock {
/* T1 transformation succeeded */ /* T1 transformation succeeded */
try { try {
System.err.println("T1 succeeded:"); // System.err.println("T1 succeeded:");
System.err.println("===in: "+in); // System.err.println("===in: "+in);
checkConsistent(); checkConsistent();
} catch (RuntimeException ex) { } catch (RuntimeException ex) {
ex.printStackTrace();
try { try {
jode.TabbedPrintWriter writer = jode.TabbedPrintWriter writer =
new jode.TabbedPrintWriter(System.err, " "); new jode.TabbedPrintWriter(System.err, " ");
@ -773,17 +845,18 @@ public class FlowBlock {
FlowBlock predFlow = (FlowBlock) preds.nextElement(); FlowBlock predFlow = (FlowBlock) preds.nextElement();
if (predFlow != null && predFlow != this if (predFlow != null && predFlow != this
&& !triedBlocks.contains(predFlow)) { && !triedBlocks.contains(predFlow)) {
System.err.println("refusing T2 on: "+getLabel()+ // System.err.println("refusing T2 on: "+getLabel()+
" because of "+predFlow.getLabel()); // " because of "+predFlow.getLabel());
/* XXX Is this enough to refuse T2 trafo ??? */ /* XXX Is this enough to refuse T2 trafo ??? */
return false; return false;
} }
} }
try { try {
System.err.println("doing T2 analysis on: "+getLabel()); // System.err.println("doing T2 analysis on: "+getLabel());
checkConsistent(); checkConsistent();
} catch (RuntimeException ex) { } catch (RuntimeException ex) {
ex.printStackTrace();
try { try {
jode.TabbedPrintWriter writer = jode.TabbedPrintWriter writer =
new jode.TabbedPrintWriter(System.err, " "); new jode.TabbedPrintWriter(System.err, " ");
@ -874,9 +947,10 @@ public class FlowBlock {
/* T2 analysis succeeded */ /* T2 analysis succeeded */
try { try {
System.err.println("T2 succeeded:"); // System.err.println("T2 succeeded:");
checkConsistent(); checkConsistent();
} catch (RuntimeException ex) { } catch (RuntimeException ex) {
ex.printStackTrace();
try { try {
jode.TabbedPrintWriter writer = jode.TabbedPrintWriter writer =
new jode.TabbedPrintWriter(System.err, " "); new jode.TabbedPrintWriter(System.err, " ");
@ -914,6 +988,12 @@ public class FlowBlock {
predecessors.addElement(null); predecessors.addElement(null);
} }
public void addSuccessor(Jump jump) {
successors.addElement(jump);
if (!jump.destination.predecessors.contains(this))
jump.destination.predecessors.addElement(this);
}
public void removeSuccessor(Jump jump) { public void removeSuccessor(Jump jump) {
successors.setElementAt(null, successors.indexOf(jump)); successors.setElementAt(null, successors.indexOf(jump));
} }
@ -969,4 +1049,11 @@ public class FlowBlock {
label = "flow_"+addr+"_"+(serialno++)+"_"; label = "flow_"+addr+"_"+(serialno++)+"_";
return label; return label;
} }
/**
* Returns the structured block, that this flow block contains.
*/
public StructuredBlock getBlock() {
return block;
}
} }

@ -42,24 +42,119 @@ import jode.TabbedPrintWriter;
public class RawTryCatchBlock extends StructuredBlock { public class RawTryCatchBlock extends StructuredBlock {
public RawTryCatchBlock(sun.tools.java.Type type,
StructuredBlock tryBlock,
Jump endDest, Jump catchDest) {
this.type = type;
endBlock = new EmptyBlock(endDest);
endBlock.outer = this;
catchBlock = new EmptyBlock(catchDest);
catchBlock.outer = this;
replace(tryBlock, tryBlock);
this.tryBlock = tryBlock;
tryBlock.outer = this;
endBlock.setFlowBlock(flowBlock);
if (tryBlock instanceof RawTryCatchBlock
&& ((RawTryCatchBlock)tryBlock).endBlock.jump.destination
== endDest.destination)
endBlock.jump = null;
else
flowBlock.addSuccessor(endDest);
catchBlock.setFlowBlock(flowBlock);
flowBlock.addSuccessor(catchDest);
}
/**
* The try block.
*/
StructuredBlock tryBlock;
/** /**
* An unconditional jump to the EndBlock. * An empty block containing an unconditional jump to the EndBlock.
* Or null if the try block is completely read.
*/ */
Jump EndBlock; StructuredBlock endBlock;
/** /**
* An unconditional jump to the CatchBlock. * The catch block.
*/ */
Jump CatchBlock; StructuredBlock catchBlock;
/** /**
* The type of the exception that is catched. This is null for a * The type of the exception that is catched. This is null for a
* synchronized/finally block * synchronized/finally block
*/ */
jode.MyType type; sun.tools.java.Type type;
/**
* Replaces the given sub block with a new block.
* @param oldBlock the old sub block.
* @param newBlock the new sub block.
* @return false, if oldBlock wasn't a direct sub block.
*/
public boolean replaceSubBlock(StructuredBlock oldBlock,
StructuredBlock newBlock) {
if (tryBlock == oldBlock) {
tryBlock = newBlock;
if (tryBlock instanceof RawTryCatchBlock
&& ((RawTryCatchBlock)tryBlock).endBlock.jump.destination
== endBlock.jump.destination) {
endBlock.removeJump();
}
} else if (endBlock == oldBlock)
endBlock = newBlock;
else if (catchBlock == oldBlock)
catchBlock = newBlock;
else
return false;
return true;
}
/**
* Returns all sub block of this structured block.
*/
public StructuredBlock[] getSubBlocks() {
StructuredBlock[] result = { tryBlock, endBlock, catchBlock };
return result;
}
// /**
// * Determines if there is a sub block, that flows through to the end
// * of this block. If this returns true, you know that jump is null.
// * @return true, if the jump may be safely changed.
// */
// public boolean jumpMayBeChanged() {
// return ( tryBlock.jump != null || tryBlock.jumpMayBeChanged())
// && (catchBlock.jump != null || catchBlock.jumpMayBeChanged());
// }
public void dumpInstruction(TabbedPrintWriter writer) public void dumpInstruction(TabbedPrintWriter writer)
throws java.io.IOException { throws java.io.IOException {
writer.println("IMPLEMENT FINALLY"); writer.println("TRY "+(type != null ? type.toString() : "ALL"));
writer.tab();
tryBlock.dumpSource(writer);
writer.untab();
writer.println("UNTIL");
writer.tab();
endBlock.dumpSource(writer);
writer.untab();
writer.println("CATCH TO");
writer.tab();
catchBlock.dumpSource(writer);
writer.untab();
}
public StructuredBlock getTryBlock() {
return tryBlock;
}
public int getCatchAddr() {
return catchBlock.jump.destination.addr;
} }
} }

Loading…
Cancel
Save