1 19 20 package jode.flow; 21 import jode.type.Type; 22 import jode.decompiler.LocalInfo; 23 import jode.decompiler.Declarable; 24 import jode.expr.Expression; 25 import jode.expr.LocalLoadOperator; 26 import jode.expr.LocalStoreOperator; 27 import jode.expr.NopOperator; 28 import jode.expr.StoreInstruction; 29 import jode.util.SimpleSet; 30 31 import java.util.Collections ; 32 import java.util.Iterator ; 33 import java.util.Set ; 34 35 36 40 public class CatchBlock extends StructuredBlock { 41 42 45 StructuredBlock catchBlock; 46 47 50 Type exceptionType; 51 52 55 LocalInfo exceptionLocal; 56 57 public CatchBlock(Type type) { 58 exceptionType = type; 59 } 60 61 public Type getExceptionType() { 62 return exceptionType; 63 } 64 65 public LocalInfo getLocal() { 66 return exceptionLocal; 67 } 68 69 73 public void setCatchBlock(StructuredBlock catchBlock) { 74 this.catchBlock = catchBlock; 75 catchBlock.outer = this; 76 catchBlock.setFlowBlock(flowBlock); 77 if (exceptionLocal == null) 78 combineLocal(); 79 } 80 81 83 84 90 public boolean replaceSubBlock(StructuredBlock oldBlock, 91 StructuredBlock newBlock) { 92 if (catchBlock == oldBlock) 93 catchBlock = newBlock; 94 else 95 return false; 96 return true; 97 } 98 99 102 public StructuredBlock[] getSubBlocks() { 103 return new StructuredBlock[] { catchBlock }; 104 } 105 106 LocalInfo pushedLocal; 107 108 114 public VariableStack mapStackToLocal(VariableStack stack) { 115 VariableStack newStack; 116 if (exceptionLocal == null) { 117 pushedLocal = new LocalInfo(); 118 pushedLocal.setType(exceptionType); 119 newStack = stack.push(pushedLocal); 120 } else 121 newStack = stack; 122 return super.mapStackToLocal(newStack); 123 } 124 125 public void removePush() { 126 if (pushedLocal != null) 127 exceptionLocal = pushedLocal; 128 super.removePush(); 129 } 130 131 public Set getDeclarables() { 132 if (exceptionLocal != null) 133 return Collections.singleton(exceptionLocal); 134 return Collections.EMPTY_SET; 135 } 136 137 143 public void makeDeclaration(Set done) { 144 super.makeDeclaration(done); 145 151 if (exceptionLocal != null) { 152 if (declare.contains(exceptionLocal)) 153 declare.remove(exceptionLocal); 154 else { 155 LocalInfo dummyLocal = new LocalInfo(); 156 Expression store = new StoreInstruction 157 (new LocalStoreOperator 158 (exceptionLocal.getType(), exceptionLocal)).addOperand 159 (new LocalLoadOperator(dummyLocal.getType(), 160 null, dummyLocal)); 161 InstructionBlock ib = new InstructionBlock(store); 162 ib.setFlowBlock(flowBlock); 163 ib.appendBlock(catchBlock); 164 catchBlock = ib; 165 exceptionLocal = dummyLocal; 166 String localName = dummyLocal.guessName(); 167 Iterator doneIter = done.iterator(); 168 while (doneIter.hasNext()) { 169 Declarable previous = (Declarable) doneIter.next(); 170 if (localName.equals(previous.getName())) { 171 172 dummyLocal.makeNameUnique(); 173 break; 174 } 175 } 176 } 177 } 178 } 179 180 public void dumpInstruction(jode.decompiler.TabbedPrintWriter writer) 181 throws java.io.IOException { 182 writer.closeBraceContinue(); 183 writer.print("catch ("); 184 writer.printType(exceptionType); 185 writer.print(" " + (exceptionLocal != null 186 ? exceptionLocal.getName() : "PUSH") + ")"); 187 writer.openBrace(); 188 writer.tab(); 189 catchBlock.dumpSource(writer); 190 writer.untab(); 191 } 192 193 198 public boolean jumpMayBeChanged() { 199 return (catchBlock.jump != null || catchBlock.jumpMayBeChanged()); 200 } 201 202 207 public boolean combineLocal() { 208 StructuredBlock firstInstr = (catchBlock instanceof SequentialBlock) 209 ? catchBlock.getSubBlocks()[0] : catchBlock; 210 211 if (firstInstr instanceof SpecialBlock 212 && ((SpecialBlock) firstInstr).type == SpecialBlock.POP 213 && ((SpecialBlock) firstInstr).count == 1) { 214 215 exceptionLocal = new LocalInfo(); 216 exceptionLocal.setType(exceptionType); 217 firstInstr.removeBlock(); 218 return true; 219 } else if (firstInstr instanceof InstructionBlock) { 220 Expression instr = 221 ((InstructionBlock) firstInstr).getInstruction(); 222 if (instr instanceof StoreInstruction) { 223 StoreInstruction store = (StoreInstruction) instr; 224 if (store.getOperatorIndex() == store.OPASSIGN_OP 225 && store.getSubExpressions()[1] instanceof NopOperator 226 && store.getLValue() instanceof LocalStoreOperator) { 227 228 exceptionLocal = ((LocalStoreOperator) store.getLValue()) 229 .getLocalInfo(); 230 exceptionLocal.setType(exceptionType); 231 firstInstr.removeBlock(); 232 return true; 233 } 234 } 235 } 236 return false; 237 } 238 } 239 | Popular Tags |