*** empty log message ***

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@35 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 26 years ago
parent 294026c0f8
commit 674d865943
  1. 57
      jode/jode/decompiler/CodeAnalyzer.java
  2. 40
      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.io.*;
import jode.flow.FlowBlock;
import jode.flow.Jump;
import jode.flow.StructuredBlock;
import jode.flow.RawTryCatchBlock;
public class CodeAnalyzer implements Analyzer, Constants {
@ -31,6 +34,7 @@ public class CodeAnalyzer implements Analyzer, Constants {
MethodAnalyzer method;
public JodeEnvironment env;
jode.flow.VariableSet param;
LocalVariableTable lvt;
/**
@ -73,26 +77,43 @@ public class CodeAnalyzer implements Analyzer, Constants {
} catch (IOException ex) {
throw new ClassFormatError(ex.toString());
}
BinaryExceptionHandler[] handlers = bincode.getExceptionHandlers();
for (int addr=0; addr<instr.length; ) {
instr[addr].resolveJumps(instr);
addr = instr[addr].getNextAddr();
}
methodHeader = instr[0];
methodHeader.makeStartBlock();
/* XXX do something with handlers */
}
/*
tryAddrs.put(new Integer(handler.startPC), handler);
references[handler.startPC]++;
catchAddrs.put(new Integer(handler.handlerPC), handler);
references[handler.handlerPC]++;
*/
BinaryExceptionHandler[] handlers = bincode.getExceptionHandlers();
for (int i=0; i<handlers.length; i++) {
StructuredBlock tryBlock = instr[handlers[i].startPC].getBlock();
while (tryBlock instanceof RawTryCatchBlock
&& (((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)
throws java.io.IOException
{
methodHeader.makeDeclaration(param);
methodHeader.dumpSource(writer);
}
@ -109,18 +130,22 @@ public class CodeAnalyzer implements Analyzer, Constants {
if (lvt != null)
return lvt.getLocal(slot).getInfo(addr);
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 = {
new jode.flow.RemoveEmpty(),
// new CombineCatchLocal(),
new jode.flow.CreateExpression(),
// new CreatePostIncExpression(),
// new CreateAssignExpression(),
new jode.flow.CreatePostIncExpression(),
new jode.flow.CreateAssignExpression(),
new jode.flow.CreateNewConstructor(),
new jode.flow.CombineIfGotoExpressions(),
// new CreateIfThenElseOperator(),
new jode.flow.CreateIfThenElseOperator(),
// new CreateConstantArray(),
new jode.flow.SimplifyExpression()
};
@ -176,14 +201,16 @@ public class CodeAnalyzer implements Analyzer, Constants {
*
* Otherwise flow transformation didn't succeeded.
*/
System.err.println("breaking analyzation; flow: "
+ flow.getLabel());
// System.err.println("breaking analyzation; flow: "
// + flow.getLabel());
while (!todo.isEmpty()) {
System.err.println("on Stack: "
+ ((FlowBlock)todo.pop()).getLabel());
}
break analyzation;
}
if (Decompiler.isVerbose)
System.err.print(".");
}
}

@ -50,29 +50,36 @@ public class MethodAnalyzer implements Analyzer, Constants {
}
public void analyze()
throws ClassFormatError
throws ClassFormatError
{
if (code == null)
return;
// if (Decompiler.isVerbose)
// System.err.print(mdef.getName().toString()+": ");
// lva.createLocalInfo(code);
// code.analyze();
// if (Decompiler.isVerbose)
// System.err.println("");
}
int offset = 0;
if (!mdef.isStatic()) {
LocalInfo clazz = code.getParamInfo(0);
clazz.setType(mdef.getClassDefinition().getType());
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)
throws java.io.IOException
{
if (code != null) {
if (Decompiler.isVerbose)
System.err.print(mdef.getName().toString()+": ");
// lva.createLocalInfo(code);
code.analyze();
if (Decompiler.isVerbose)
System.err.println("");
}
if (Decompiler.isVerbose)
System.err.print(mdef.getName().toString()+": ");
code.analyze();
if (Decompiler.isVerbose)
System.err.println("");
}
writer.println("");
String modif = Modifier.toString(mdef.getModifiers());
@ -97,7 +104,7 @@ public class MethodAnalyzer implements Analyzer, Constants {
env.getTypeString(paramTypes[i]):
env.getTypeString
(paramTypes[i],
code.getLocalInfo(-1, i+offset).getName()));
code.getParamInfo(i+offset).getName()));
}
writer.print(")");
}
@ -116,7 +123,6 @@ public class MethodAnalyzer implements Analyzer, Constants {
if (code != null) {
writer.println(" {");
writer.tab();
// lva.dumpSource(writer);
code.dumpSource(writer);
writer.untab();
writer.println("}");

@ -104,6 +104,34 @@ public class FlowBlock {
public int getNextAddr() {
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.
@ -238,9 +266,22 @@ public class FlowBlock {
SequentialBlock sequBlock = new SequentialBlock();
StructuredBlock prevBlock = jump.prev;
prevBlock.removeJump();
sequBlock.replace(prevBlock, prevBlock);
sequBlock.setFirst(prevBlock);
sequBlock.setSecond(new ReturnBlock());
if (prevBlock instanceof EmptyBlock) {
if (prevBlock.outer instanceof ConditionalBlock) {
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;
}
@ -331,12 +372,27 @@ public class FlowBlock {
else
prevBlock.removeJump();
sequBlock.replace(prevBlock, prevBlock);
sequBlock.setFirst(prevBlock);
sequBlock.setSecond
(new BreakBlock((BreakableBlock) surrounder,
breaklevel > 1));
continue next_jump;
if (prevBlock instanceof EmptyBlock) {
if (prevBlock.outer instanceof ConditionalBlock) {
IfThenElseBlock ifBlock =
new IfThenElseBlock
(((ConditionalBlock)prevBlock.outer)
.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);
}
System.err.println("UpdateInOut: allOuts : "+allOuts);
System.err.println(" intersectOut: "+intersectOut);
// System.err.println("UpdateInOut: allOuts : "+allOuts);
// System.err.println(" intersectOut: "+intersectOut);
/* Merge the locals used in successing block with those written
* by this blocks
@ -382,7 +438,7 @@ public class FlowBlock {
VariableSet defineHere = successor.in.merge(allOuts);
defineHere.subtractExact(in);
System.err.println(" defineHere : "+defineHere);
// System.err.println(" defineHere : "+defineHere);
if (t1Transformation) {
/* Now update in and out set of successing block */
successor.in.subtract(intersectOut);
@ -394,9 +450,9 @@ public class FlowBlock {
jump.out.add(intersectOut);
}
}
System.err.println(" successor.in: "+successor.in);
// System.err.println(" successor.in: "+successor.in);
in.union(successor.in);
System.err.println(" in : "+in);
// System.err.println(" in : "+in);
/* XXX - do something with defineHere */
return defineHere; /*XXX - correct???*/
}
@ -484,7 +540,7 @@ public class FlowBlock {
if (prevSucc != null && fb.addr <= prevSucc.addr)
continue;
if (succ == null || fb.addr < succ.addr) {
System.err.println("trying "+fb.getLabel());
// System.err.println("trying "+fb.getLabel());
succ = fb;
}
}
@ -546,13 +602,14 @@ public class FlowBlock {
return false;
try{
System.err.println("doing T1 analysis on: "+getLabel());
System.err.println("***in: "+in);
// System.err.println("doing T1 analysis on: "+getLabel());
// System.err.println("***in: "+in);
checkConsistent();
System.err.println("and "+succ.getLabel());
System.err.println("+++in: "+succ.in);
// System.err.println("and "+succ.getLabel());
// System.err.println("+++in: "+succ.in);
succ.checkConsistent();
} catch (RuntimeException ex) {
ex.printStackTrace();
try {
jode.TabbedPrintWriter writer =
new jode.TabbedPrintWriter(System.err, " ");
@ -573,8 +630,19 @@ public class FlowBlock {
if (jump == null || jump.destination != succ)
continue;
while (!appendBlock.contains(jump.prev))
while (!appendBlock.contains(jump.prev)) {
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
* outermost block contains every structured block.
*/
@ -650,9 +718,10 @@ public class FlowBlock {
}
try {
System.err.println("before optimizeJump: "+getLabel());
// System.err.println("before optimizeJump: "+getLabel());
checkConsistent();
} catch (RuntimeException ex) {
ex.printStackTrace();
try {
jode.TabbedPrintWriter writer =
new jode.TabbedPrintWriter(System.err, " ");
@ -668,9 +737,10 @@ public class FlowBlock {
appendBlock = optimizeJumps(succ, appendBlock);
try {
System.err.println("after optimizeJump: "+getLabel());
// System.err.println("after optimizeJump: "+getLabel());
checkConsistent();
} catch (RuntimeException ex) {
ex.printStackTrace();
try {
jode.TabbedPrintWriter writer =
new jode.TabbedPrintWriter(System.err, " ");
@ -703,6 +773,7 @@ public class FlowBlock {
LoopBlock.FALSE);
int breaklevel = 1;
Jump debug=jump;
for (StructuredBlock surrounder = jump.prev.outer;
surrounder != appendBlock.outer;
surrounder = surrounder.outer) {
@ -745,10 +816,11 @@ public class FlowBlock {
/* T1 transformation succeeded */
try {
System.err.println("T1 succeeded:");
System.err.println("===in: "+in);
// System.err.println("T1 succeeded:");
// System.err.println("===in: "+in);
checkConsistent();
} catch (RuntimeException ex) {
ex.printStackTrace();
try {
jode.TabbedPrintWriter writer =
new jode.TabbedPrintWriter(System.err, " ");
@ -773,17 +845,18 @@ public class FlowBlock {
FlowBlock predFlow = (FlowBlock) preds.nextElement();
if (predFlow != null && predFlow != this
&& !triedBlocks.contains(predFlow)) {
System.err.println("refusing T2 on: "+getLabel()+
" because of "+predFlow.getLabel());
// System.err.println("refusing T2 on: "+getLabel()+
// " because of "+predFlow.getLabel());
/* XXX Is this enough to refuse T2 trafo ??? */
return false;
}
}
try {
System.err.println("doing T2 analysis on: "+getLabel());
// System.err.println("doing T2 analysis on: "+getLabel());
checkConsistent();
} catch (RuntimeException ex) {
ex.printStackTrace();
try {
jode.TabbedPrintWriter writer =
new jode.TabbedPrintWriter(System.err, " ");
@ -874,9 +947,10 @@ public class FlowBlock {
/* T2 analysis succeeded */
try {
System.err.println("T2 succeeded:");
// System.err.println("T2 succeeded:");
checkConsistent();
} catch (RuntimeException ex) {
ex.printStackTrace();
try {
jode.TabbedPrintWriter writer =
new jode.TabbedPrintWriter(System.err, " ");
@ -914,6 +988,12 @@ public class FlowBlock {
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) {
successors.setElementAt(null, successors.indexOf(jump));
}
@ -969,4 +1049,11 @@ public class FlowBlock {
label = "flow_"+addr+"_"+(serialno++)+"_";
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 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
* 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)
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