handle the exceptionLocal ourself

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@816 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 26 years ago
parent d09390083d
commit f0aea2b5ad
  1. 89
      jode/jode/flow/CatchBlock.java

@ -20,6 +20,10 @@
package jode.flow; package jode.flow;
import jode.type.Type; import jode.type.Type;
import jode.decompiler.LocalInfo; import jode.decompiler.LocalInfo;
import jode.expr.Expression;
import jode.expr.LocalLoadOperator;
import jode.expr.LocalStoreOperator;
import jode.expr.StoreInstruction;
/** /**
* *
@ -42,12 +46,8 @@ public class CatchBlock extends StructuredBlock {
*/ */
LocalInfo exceptionLocal; LocalInfo exceptionLocal;
CatchBlock() { public CatchBlock(Type type) {
}
public CatchBlock(Type type, LocalInfo local) {
exceptionType = type; exceptionType = type;
exceptionLocal = local;
} }
public Type getExceptionType() { public Type getExceptionType() {
@ -66,6 +66,8 @@ public class CatchBlock extends StructuredBlock {
this.catchBlock = catchBlock; this.catchBlock = catchBlock;
catchBlock.outer = this; catchBlock.outer = this;
catchBlock.setFlowBlock(flowBlock); catchBlock.setFlowBlock(flowBlock);
if (exceptionLocal == null)
combineLocal();
} }
/* The implementation of getNext[Flow]Block is the standard /* The implementation of getNext[Flow]Block is the standard
@ -118,27 +120,41 @@ public class CatchBlock extends StructuredBlock {
super.removePush(); super.removePush();
} }
public VariableSet propagateUsage() { public VariableSet getUsed() {
if (used == null) used = new VariableSet();
used = new VariableSet(); /*XXX*/
if (exceptionLocal != null) if (exceptionLocal != null)
used.addElement(exceptionLocal); used.addElement(exceptionLocal);
return super.propagateUsage(); return used;
} }
/** /**
* Print the code for the declaration of a local variable. * Make the declarations, i.e. initialize the declare variable
* @param writer The tabbed print writer, where we print to. * to correct values. This will declare every variable that
* @param local The local that should be declared. * is marked as used, but not done.
* @param done The set of the already declare variables.
*/ */
public void dumpDeclaration(jode.decompiler.TabbedPrintWriter writer, LocalInfo local) public void makeDeclaration(VariableSet done) {
throws java.io.IOException super.makeDeclaration(done);
{ /* Normally we have to declare our exceptionLocal. This
if (local != exceptionLocal) { * is automatically done in dumpSource.
/* exceptionLocal will be automatically declared in *
* dumpInstruction. * If we are unlucky the exceptionLocal is used outside of
* this block. In that case we do a transformation.
*/ */
super.dumpDeclaration(writer, local); if (declare.contains(exceptionLocal))
declare.removeElement(exceptionLocal);
else {
LocalInfo dummyLocal = new LocalInfo();
Expression store = new StoreInstruction
(new LocalStoreOperator
(exceptionLocal.getType(), exceptionLocal)).addOperand
(new LocalLoadOperator(dummyLocal.getType(),
null, dummyLocal));
InstructionBlock ib = new InstructionBlock(store);
ib.setFlowBlock(flowBlock);
ib.appendBlock(catchBlock);
catchBlock = ib;
exceptionLocal = dummyLocal;
} }
} }
@ -163,4 +179,39 @@ public class CatchBlock extends StructuredBlock {
public boolean jumpMayBeChanged() { public boolean jumpMayBeChanged() {
return (catchBlock.jump != null || catchBlock.jumpMayBeChanged()); return (catchBlock.jump != null || catchBlock.jumpMayBeChanged());
} }
/**
* Check if this is an local store instruction to a not yet declared
* variable. In that case mark this as declaration and return the
* variable.
*/
public boolean combineLocal() {
StructuredBlock firstInstr = (catchBlock instanceof SequentialBlock)
? catchBlock.getSubBlocks()[0] : catchBlock;
if (firstInstr instanceof SpecialBlock
&& ((SpecialBlock) firstInstr).type == SpecialBlock.POP
&& ((SpecialBlock) firstInstr).count == 1) {
/* The exception is ignored. Create a dummy local for it */
exceptionLocal = new LocalInfo();
exceptionLocal.setType(exceptionType);
firstInstr.removeBlock();
return true;
} else if (firstInstr instanceof InstructionBlock) {
Expression instr =
((InstructionBlock) firstInstr).getInstruction();
if (instr instanceof StoreInstruction
&& (((StoreInstruction)instr).getLValue()
instanceof LocalStoreOperator)) {
/* The exception is stored in a local variable */
exceptionLocal = ((LocalStoreOperator)
((StoreInstruction)instr).getLValue())
.getLocalInfo();
exceptionLocal.setType(exceptionType);
firstInstr.removeBlock();
return true;
}
}
return false;
}
} }

Loading…
Cancel
Save