1 19 20 package jode.flow; 21 import jode.decompiler.TabbedPrintWriter; 22 import jode.expr.*; 23 24 27 public class SpecialBlock extends StructuredBlock { 28 29 public static int DUP = 0; 30 public static int SWAP = 1; 31 public static int POP = 2; 32 private static String [] output = { "DUP", "SWAP", "POP" }; 33 34 37 int type; 38 42 int count; 43 47 int depth; 48 49 public SpecialBlock(int type, int count, int depth, Jump jump) { 50 this.type = type; 51 this.count = count; 52 this.depth = depth; 53 setJump(jump); 54 } 55 56 62 public VariableStack mapStackToLocal(VariableStack stack) { 63 64 VariableStack after = stack.executeSpecial(this); 65 return super.mapStackToLocal(after); 66 } 67 68 public void removePush() { 69 70 removeBlock(); 71 } 72 73 74 public void dumpInstruction(TabbedPrintWriter writer) 75 throws java.io.IOException 76 { 77 writer.println(output[type] 78 + ((count == 1) ? "" : "2") 79 + ((depth == 0) ? "" : "_X"+depth)); 80 } 81 82 public boolean doTransformations() { 83 return (type == SWAP && removeSwap(flowBlock.lastModified)) 84 || (type == POP && removePop(flowBlock.lastModified)); 85 } 86 87 public boolean removeSwap(StructuredBlock last) { 88 89 100 if (last.outer instanceof SequentialBlock 101 && last.outer.outer instanceof SequentialBlock 102 && last.outer.getSubBlocks()[0] instanceof InstructionBlock 103 && last.outer.outer.getSubBlocks()[0] 104 instanceof InstructionBlock) { 105 106 InstructionBlock block1 107 = (InstructionBlock) last.outer.outer.getSubBlocks()[0]; 108 InstructionBlock block2 109 = (InstructionBlock) last.outer.getSubBlocks()[0]; 110 111 Expression expr1 = block1.getInstruction(); 112 Expression expr2 = block2.getInstruction(); 113 114 if (expr1.isVoid() || expr2.isVoid() 115 || expr1.getFreeOperandCount() != 0 116 || expr2.getFreeOperandCount() != 0 117 || expr1.hasSideEffects(expr2) 118 || expr2.hasSideEffects(expr1)) 119 return false; 120 121 126 last.outer.replace(block1.outer); 127 131 block1.replace(this); 132 block1.moveJump(jump); 133 136 block1.flowBlock.lastModified = block1; 137 return true; 138 } 139 return false; 140 } 141 142 public boolean removePop(StructuredBlock last) { 143 144 167 168 if (last.outer instanceof SequentialBlock 169 && last.outer.getSubBlocks()[0] instanceof InstructionBlock) { 170 171 if (jump != null && jump.destination == null) 172 return false; 173 174 InstructionBlock prev 175 = (InstructionBlock) last.outer.getSubBlocks()[0]; 176 Expression instr = prev.getInstruction(); 177 178 if (instr.getType().stackSize() == count) { 179 StructuredBlock newBlock; 180 if (instr instanceof InvokeOperator 181 || instr instanceof StoreInstruction) { 182 Expression newExpr 183 = new PopOperator(instr.getType()).addOperand(instr); 184 prev.setInstruction(newExpr); 185 newBlock = prev; 186 } else { 187 Expression newCond = new CompareUnaryOperator 188 (instr.getType(), Operator.NOTEQUALS_OP) 189 .addOperand(instr); 190 IfThenElseBlock newIfThen = new IfThenElseBlock(newCond); 191 newIfThen.setThenBlock(new EmptyBlock()); 192 newBlock = newIfThen; 193 } 194 newBlock.moveDefinitions(last.outer, last); 197 newBlock.moveJump(jump); 198 if (this == last) { 199 newBlock.replace(last.outer); 200 flowBlock.lastModified = newBlock; 201 } else { 202 newBlock.replace(this); 203 last.replace(last.outer); 204 } 205 return true; 206 } 207 } 208 return false; 209 } 210 } 211 | Popular Tags |