| 1 19 20 package soot.javaToJimple.toolkits; 21 22 import soot.*; 23 import soot.jimple.*; 24 import java.util.*; 25 26 public class CondTransformer extends BodyTransformer { 27 public CondTransformer (Singletons.Global g) {} 28 public static CondTransformer v() { 29 return G.v().soot_javaToJimple_toolkits_CondTransformer(); 30 } 31 32 private static final int SEQ_LENGTH = 6; 33 private Stmt [] stmtSeq = new Stmt[SEQ_LENGTH]; 34 private boolean sameGoto = true; 35 36 protected void internalTransform(Body b, String phaseName, Map options){ 37 38 boolean change = true; 40 58 59 while (change){ 60 Iterator it = b.getUnits().iterator(); 61 int pos = 0; 62 while (it.hasNext()){ 63 change = false; 64 Stmt s = (Stmt)it.next(); 65 if (testStmtSeq(s, pos)) { 66 pos++; 67 } 68 if (pos == 6) { 69 change = true; 72 break; 73 } 74 } 75 if (change){ 76 transformBody(b, (Stmt)it.next()); 77 pos = 0; 78 stmtSeq = new Stmt[SEQ_LENGTH]; 79 } 80 } 81 } 82 83 private void transformBody(Body b, Stmt next){ 84 Stmt newTarget = null; 87 Stmt oldTarget = null; 88 if (sameGoto){ 89 newTarget = ((IfStmt)stmtSeq[5]).getTarget(); 90 } 91 else { 92 newTarget = next; 93 oldTarget = ((IfStmt)stmtSeq[5]).getTarget(); 94 } 95 ((IfStmt)stmtSeq[0]).setTarget(newTarget); 96 ((IfStmt)stmtSeq[1]).setTarget(newTarget); 97 98 for (int i = 2; i <= 5; i++){ 99 b.getUnits().remove(stmtSeq[i]); 100 } 101 if (!sameGoto){ 102 b.getUnits().insertAfter(Jimple.v().newGotoStmt(oldTarget), stmtSeq[1]); 103 } 104 } 105 106 private boolean testStmtSeq(Stmt s, int pos){ 107 switch(pos){ 108 case 0: { 109 if (s instanceof IfStmt){ 110 stmtSeq[pos] = s; 111 return true; 112 } 113 break; 114 } 115 case 1: { 116 if (s instanceof IfStmt){ 117 if (sameTarget(stmtSeq[pos-1], s)){ 118 stmtSeq[pos] = s; 119 return true; 120 } 121 } 122 break; 123 } 124 case 2: { 125 if (s instanceof AssignStmt){ 126 stmtSeq[pos] = s; 127 if ((((AssignStmt)s).getRightOp() instanceof IntConstant) && (((IntConstant)((AssignStmt)s).getRightOp())).value == 0){ 128 sameGoto = false; 129 } 130 return true; 131 } 132 break; 133 } 134 case 3: { 135 if (s instanceof GotoStmt){ 136 stmtSeq[pos] = s; 137 return true; 138 } 139 break; 140 } 141 case 4: { 142 if (s instanceof AssignStmt){ 143 if (isTarget(((IfStmt)stmtSeq[0]).getTarget(), s) && sameLocal(stmtSeq[2], s)){ 144 stmtSeq[pos] = s; 145 return true; 146 } 147 } 148 break; 149 } 150 case 5: { 151 if (s instanceof IfStmt){ 152 if (isTarget((Stmt)((GotoStmt)stmtSeq[3]).getTarget(), s) && sameCondLocal(stmtSeq[4], s) && (((IfStmt)s).getCondition() instanceof EqExpr)){ 153 stmtSeq[pos] = s; 154 return true; 155 } 156 else if (isTarget((Stmt)((GotoStmt)stmtSeq[3]).getTarget(), s) && sameCondLocal(stmtSeq[4], s)){ 157 stmtSeq[pos] = s; 158 sameGoto = false; 159 return true; 160 } 161 } 162 break; 163 } 164 165 default: { 166 break; 167 } 168 } 169 return false; 170 } 171 172 private boolean sameTarget(Stmt s1, Stmt s2){ 173 IfStmt is1 = (IfStmt)s1; 174 IfStmt is2 = (IfStmt)s2; 175 if (is1.getTarget().equals(is2.getTarget())){ 176 return true; 177 } 178 return false; 179 } 180 181 private boolean isTarget(Stmt s1, Stmt s){ 182 if (s1.equals(s)){ 183 return true; 184 } 185 return false; 186 } 187 188 private boolean sameLocal(Stmt s1, Stmt s2){ 189 AssignStmt as1 = (AssignStmt)s1; 190 AssignStmt as2 = (AssignStmt)s2; 191 if (as1.getLeftOp().equals(as2.getLeftOp())){ 192 return true; 193 } 194 return false; 195 } 196 197 private boolean sameCondLocal(Stmt s1, Stmt s2){ 198 AssignStmt as1 = (AssignStmt)s1; 199 IfStmt is2 = (IfStmt)s2; 200 if (is2.getCondition() instanceof BinopExpr){ 201 BinopExpr bs2 = (BinopExpr)is2.getCondition(); 202 if (as1.getLeftOp().equals(bs2.getOp1())){ 203 return true; 204 } 205 } 206 return false; 207 } 208 } 209 | Popular Tags |