1 19 20 package jode.flow; 21 import jode.decompiler.TabbedPrintWriter; 22 import jode.expr.Expression; 23 24 27 public class SwitchBlock extends InstructionContainer 28 implements BreakableBlock { 29 CaseBlock[] caseBlocks; 30 VariableStack exprStack; 31 VariableStack breakedStack; 32 33 public SwitchBlock(Expression instr, 34 int[] cases, FlowBlock[] dests) { 35 super(instr); 36 37 38 int numCases = dests.length; 39 FlowBlock defaultDest = dests[cases.length]; 40 for (int i=0; i< cases.length; i++) { 41 if (dests[i] == defaultDest) { 42 dests[i] = null; 43 numCases--; 44 } 45 } 46 47 caseBlocks = new CaseBlock[numCases]; 48 FlowBlock lastDest = null; 49 for (int i=numCases-1; i>=0; i--) { 50 53 int index = 0; 54 for (int j=1; j<dests.length; j++) { 55 if (dests[j] != null 56 && (dests[index] == null 57 || dests[j].getAddr() >= dests[index].getAddr())) 58 index = j; 59 } 60 61 62 int value; 63 if (index == cases.length) 64 value = -1; 65 else 66 value = cases[index]; 67 68 if (dests[index] == lastDest) 69 caseBlocks[i] = new CaseBlock(value); 70 else 71 caseBlocks[i] = new CaseBlock(value, 72 new Jump(dests[index])); 73 caseBlocks[i].outer = this; 74 lastDest = dests[index]; 75 dests[index] = null; 76 if (index == cases.length) 77 caseBlocks[i].isDefault = true; 78 } 79 caseBlocks[numCases-1].isLastBlock = true; 80 this.jump = null; 81 isBreaked = false; 82 } 83 84 90 public VariableStack mapStackToLocal(VariableStack stack) { 91 VariableStack newStack; 92 int params = instr.getFreeOperandCount(); 93 if (params > 0) { 94 exprStack = stack.peek(params); 95 newStack = stack.pop(params); 96 } else 97 newStack = stack; 98 VariableStack lastStack = newStack; 99 for (int i=0; i< caseBlocks.length; i++) { 100 if (lastStack != null) 101 newStack.merge(lastStack); 102 lastStack = caseBlocks[i].mapStackToLocal(newStack); 103 } 104 if (lastStack != null) 105 mergeBreakedStack(lastStack); 106 if (jump != null) { 107 jump.stackMap = breakedStack; 108 return null; 109 } 110 return breakedStack; 111 } 112 113 117 public void mergeBreakedStack(VariableStack stack) { 118 if (breakedStack != null) 119 breakedStack.merge(stack); 120 else 121 breakedStack = stack; 122 } 123 124 public void removePush() { 125 if (exprStack != null) 126 instr = exprStack.mergeIntoExpression(instr); 127 super.removePush(); 128 } 129 130 134 public StructuredBlock findCase(FlowBlock destination) { 135 for (int i=0; i < caseBlocks.length; i++) { 136 if (caseBlocks[i].subBlock != null 137 && caseBlocks[i].subBlock instanceof EmptyBlock 138 && caseBlocks[i].subBlock.jump != null 139 && caseBlocks[i].subBlock.jump.destination == destination) 140 141 return caseBlocks[i].subBlock; 142 } 143 return null; 144 } 145 146 152 public StructuredBlock prevCase(StructuredBlock block) { 153 for (int i=caseBlocks.length-1; i>=0; i--) { 154 if (caseBlocks[i].subBlock == block) { 155 for (i--; i>=0; i--) { 156 if (caseBlocks[i].subBlock != null) 157 return caseBlocks[i].subBlock; 158 } 159 } 160 } 161 return null; 162 } 163 164 171 public StructuredBlock getNextBlock(StructuredBlock subBlock) { 172 for (int i=0; i< caseBlocks.length-1; i++) { 173 if (subBlock == caseBlocks[i]) { 174 return caseBlocks[i+1]; 175 } 176 } 177 return getNextBlock(); 178 } 179 180 public FlowBlock getNextFlowBlock(StructuredBlock subBlock) { 181 for (int i=0; i< caseBlocks.length-1; i++) { 182 if (subBlock == caseBlocks[i]) { 183 return null; 184 } 185 } 186 return getNextFlowBlock(); 187 } 188 189 public void dumpInstruction(TabbedPrintWriter writer) 190 throws java.io.IOException 191 { 192 if (label != null) { 193 writer.untab(); 194 writer.println(label+":"); 195 writer.tab(); 196 } 197 writer.print("switch ("); 198 instr.dumpExpression(writer.EXPL_PAREN, writer); 199 writer.print(")"); 200 writer.openBrace(); 201 for (int i=0; i < caseBlocks.length; i++) 202 caseBlocks[i].dumpSource(writer); 203 writer.closeBrace(); 204 } 205 206 209 public StructuredBlock[] getSubBlocks() { 210 return caseBlocks; 211 } 212 213 boolean isBreaked = false; 214 215 218 static int serialno = 0; 219 220 223 String label = null; 224 225 229 public String getLabel() { 230 if (label == null) 231 label = "switch_"+(serialno++)+"_"; 232 return label; 233 } 234 235 238 public void setBreaked() { 239 isBreaked = true; 240 } 241 242 247 public boolean jumpMayBeChanged() { 248 return !isBreaked 249 && (caseBlocks[caseBlocks.length-1].jump != null 250 || caseBlocks[caseBlocks.length-1].jumpMayBeChanged()); 251 } 252 } 253 | Popular Tags |