From f0aea2b5ad1e261a8cc56a5763a1cb81a3715ced Mon Sep 17 00:00:00 2001 From: jochen Date: Fri, 14 May 1999 12:08:05 +0000 Subject: [PATCH] handle the exceptionLocal ourself git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@816 379699f6-c40d-0410-875b-85095c16579e --- jode/jode/flow/CatchBlock.java | 95 ++++++++++++++++++++++++++-------- 1 file changed, 73 insertions(+), 22 deletions(-) diff --git a/jode/jode/flow/CatchBlock.java b/jode/jode/flow/CatchBlock.java index 133a1cf..7f4ebcc 100644 --- a/jode/jode/flow/CatchBlock.java +++ b/jode/jode/flow/CatchBlock.java @@ -20,6 +20,10 @@ package jode.flow; import jode.type.Type; 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; - CatchBlock() { - } - - public CatchBlock(Type type, LocalInfo local) { + public CatchBlock(Type type) { exceptionType = type; - exceptionLocal = local; } public Type getExceptionType() { @@ -66,6 +66,8 @@ public class CatchBlock extends StructuredBlock { this.catchBlock = catchBlock; catchBlock.outer = this; catchBlock.setFlowBlock(flowBlock); + if (exceptionLocal == null) + combineLocal(); } /* The implementation of getNext[Flow]Block is the standard @@ -118,28 +120,42 @@ public class CatchBlock extends StructuredBlock { super.removePush(); } - public VariableSet propagateUsage() { - if (used == null) - used = new VariableSet(); /*XXX*/ + public VariableSet getUsed() { + used = new VariableSet(); if (exceptionLocal != null) used.addElement(exceptionLocal); - return super.propagateUsage(); + return used; } - + /** - * Print the code for the declaration of a local variable. - * @param writer The tabbed print writer, where we print to. - * @param local The local that should be declared. + * Make the declarations, i.e. initialize the declare variable + * to correct values. This will declare every variable that + * 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) - throws java.io.IOException - { - if (local != exceptionLocal) { - /* exceptionLocal will be automatically declared in - * dumpInstruction. - */ - super.dumpDeclaration(writer, local); - } + public void makeDeclaration(VariableSet done) { + super.makeDeclaration(done); + /* Normally we have to declare our exceptionLocal. This + * is automatically done in dumpSource. + * + * If we are unlucky the exceptionLocal is used outside of + * this block. In that case we do a transformation. + */ + 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; + } } public void dumpInstruction(jode.decompiler.TabbedPrintWriter writer) @@ -163,4 +179,39 @@ public class CatchBlock extends StructuredBlock { public boolean 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; + } }