00001 package edu.ksu.cis.bandera.prog;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 import ca.mcgill.sable.soot.*;
00037 import ca.mcgill.sable.soot.jimple.*;
00038 import java.util.*;
00039 import java.util.Hashtable;
00040 public class RenameStatement extends AbstractStmtSwitch {
00041 static int count = 0;
00042 int id = ++count;
00043 String methodString;
00044 List parameters;
00045 Hashtable stmt2stmt;
00046 Value var;
00047 Stmt ret;
00048 Hashtable locals;
00049 RenameExpression re;
00050 protected edu.ksu.cis.bandera.annotation.AnnotationManager annotationManager;
00051 public RenameStatement(SootMethod method, String methodString, Value var, List parameters, Stmt ret, Hashtable locals, Hashtable stmt2stmt, SootMethod topMethod) {
00052 this.annotationManager = edu.ksu.cis.bandera.jjjc.CompilationManager.getAnnotationManager();
00053 this.methodString = methodString;
00054 this.var = var;
00055 this.parameters = parameters;
00056 this.ret = ret;
00057 this.locals = locals;
00058 this.stmt2stmt = stmt2stmt;
00059 re = new RenameExpression(methodString, parameters, locals, topMethod, method);
00060 }
00061
00062
00063
00064
00065
00066
00067 public void caseAssignStmt(AssignStmt s) {
00068 ca.mcgill.sable.util.List stmts = new ca.mcgill.sable.util.ArrayList();
00069 stmts.add(Jimple.v().newAssignStmt(re.renameExpr(s.getLeftOp()), re.renameExpr(s.getRightOp())));
00070 setResult(stmts);
00071 }
00072 public void caseEnterMonitorStmt(EnterMonitorStmt s) {
00073 ca.mcgill.sable.util.List stmts = new ca.mcgill.sable.util.ArrayList();
00074 stmts.add(Jimple.v().newEnterMonitorStmt(re.renameExpr(s.getOp())));
00075 setResult(stmts);
00076 }
00077 public void caseExitMonitorStmt(ExitMonitorStmt s) {
00078 ca.mcgill.sable.util.List stmts = new ca.mcgill.sable.util.ArrayList();
00079 stmts.add(Jimple.v().newExitMonitorStmt(re.renameExpr(s.getOp())));
00080 setResult(stmts);
00081 }
00082
00083
00084
00085
00086 public void caseGotoStmt(GotoStmt s) {
00087 ca.mcgill.sable.util.List target = (ca.mcgill.sable.util.List) stmt2stmt.get(s.getTarget());
00088 ca.mcgill.sable.util.List stmts = new ca.mcgill.sable.util.ArrayList();
00089 if (target == null) {
00090 target = renameStmt((Stmt) s.getTarget());
00091 }
00092 stmts.add(Jimple.v().newGotoStmt((Stmt) target.get(0)));
00093 setResult(stmts);
00094 }
00095
00096
00097
00098
00099 public void caseIdentityStmt(IdentityStmt s) {
00100 ca.mcgill.sable.util.List stmts = new ca.mcgill.sable.util.ArrayList();
00101 Value v = re.renameExpr(s.getRightOp());
00102 if (v instanceof ParameterRef || v instanceof ThisRef || v instanceof CaughtExceptionRef)
00103 stmts.add(Jimple.v().newIdentityStmt(re.renameExpr(s.getLeftOp()), v));
00104 else
00105 stmts.add(Jimple.v().newAssignStmt(re.renameExpr(s.getLeftOp()), v));
00106 setResult(stmts);
00107 }
00108
00109
00110
00111
00112
00113 public void caseIfStmt(IfStmt s) {
00114 ca.mcgill.sable.util.List stmts = new ca.mcgill.sable.util.ArrayList();
00115 ca.mcgill.sable.util.List target = (ca.mcgill.sable.util.List) stmt2stmt.get(s.getTarget());
00116 if (target == null) {
00117 target = renameStmt((Stmt) s.getTarget());
00118 }
00119 stmts.add(Jimple.v().newIfStmt(re.renameExpr(s.getCondition()), (Stmt) target.get(0)));
00120 setResult(stmts);
00121 }
00122 public void caseInvokeStmt(InvokeStmt s) {
00123 ca.mcgill.sable.util.List stmts = new ca.mcgill.sable.util.ArrayList();
00124 stmts.add(Jimple.v().newInvokeStmt(re.renameExpr(s.getInvokeExpr())));
00125 setResult(stmts);
00126 }
00127
00128
00129
00130
00131 public void caseLookupSwitchStmt(LookupSwitchStmt s) {
00132 ca.mcgill.sable.util.List targets = new ca.mcgill.sable.util.LinkedList();
00133 for (int i = 0; i < s.getTargetCount(); i++) {
00134 ca.mcgill.sable.util.List result = (ca.mcgill.sable.util.List) stmt2stmt.get(s.getTarget(i));
00135 ca.mcgill.sable.util.List stmts = new ca.mcgill.sable.util.ArrayList();
00136 if (result == null) {
00137 targets.add(renameStmt((Stmt) s.getTarget(i)).get(0));
00138 } else {
00139 targets.add(result.get(0));
00140 }
00141 }
00142
00143
00144 Stmt defaultTarget;
00145 {
00146 ca.mcgill.sable.util.List result = (ca.mcgill.sable.util.List) stmt2stmt.get(s.getDefaultTarget());
00147 ca.mcgill.sable.util.List stmts = new ca.mcgill.sable.util.ArrayList();
00148 if (result == null) {
00149 defaultTarget = (Stmt) renameStmt((Stmt) s.getDefaultTarget()).get(0);
00150 } else {
00151 defaultTarget = (Stmt) result.get(0);
00152 }
00153 }
00154
00155
00156 Value key = re.renameExpr(s.getKey());
00157
00158
00159 ca.mcgill.sable.util.List lookupValues = new ca.mcgill.sable.util.LinkedList();
00160 {
00161 for (ca.mcgill.sable.util.Iterator i = s.getLookupValues().iterator(); i.hasNext();) {
00162 lookupValues.add(new Integer(((Integer) i.next()).intValue()));
00163 }
00164 }
00165
00166
00167 ca.mcgill.sable.util.LinkedList stmts = new ca.mcgill.sable.util.LinkedList();
00168 stmts.add(Jimple.v().newLookupSwitchStmt(key, lookupValues, targets, defaultTarget));
00169 setResult(stmts);
00170 }
00171 public void caseNopStmt(NopStmt v) {
00172 ca.mcgill.sable.util.List l = new ca.mcgill.sable.util.VectorList();
00173 l.add(Jimple.v().newNopStmt());
00174 setResult(l);
00175 }
00176
00177
00178
00179
00180
00181
00182 public void caseReturnStmt(ReturnStmt s) {
00183 ca.mcgill.sable.util.List stmts = new ca.mcgill.sable.util.ArrayList();
00184 if (var == null)
00185 stmts.add(Jimple.v().newReturnStmt(re.renameExpr(s.getReturnValue())));
00186 else {
00187 Stmt stmt = Jimple.v().newAssignStmt(var, re.renameExpr(s.getReturnValue()));
00188 stmts.add(stmt);
00189 stmt2stmt.put(s, stmts);
00190 stmt = Jimple.v().newGotoStmt(ret);
00191 stmts.add(stmt);
00192 }
00193 setResult(stmts);
00194 }
00195
00196
00197
00198
00199
00200 public void caseReturnVoidStmt(ReturnVoidStmt s) {
00201 ca.mcgill.sable.util.List stmts = new ca.mcgill.sable.util.ArrayList();
00202 if (ret == null)
00203 stmts.add(Jimple.v().newReturnVoidStmt());
00204 else {
00205 Stmt stmt = Jimple.v().newGotoStmt(ret);
00206 stmts.add(stmt);
00207 }
00208 setResult(stmts);
00209 }
00210 public void caseThrowStmt(ThrowStmt s) {
00211 ca.mcgill.sable.util.List stmts = new ca.mcgill.sable.util.ArrayList();
00212 stmts.add(Jimple.v().newThrowStmt(re.renameExpr(s.getOp())));
00213 setResult(stmts);
00214 }
00215 public void defaultCase(Object obj) {
00216 System.out.println("Unhandled Statement: " + obj.getClass() + "\n\t " + obj);
00217 throw new RuntimeException("Unhandled Statement: " + obj.getClass());
00218
00219 }
00220
00221
00222
00223
00224
00225 public RenameExpression getRenameExpr() {
00226 return re;
00227 }
00228
00229
00230
00231
00232
00233 public static boolean javaPrefix(String s) {
00234 if (s.length() >= 4)
00235 return s.substring(0, 4).equals("java");
00236 else
00237 return false;
00238 }
00239 protected ca.mcgill.sable.util.List renameStmt(Stmt s) {
00240 if (stmt2stmt.get(s) != null)
00241 return (ca.mcgill.sable.util.List) stmt2stmt.get(s);
00242 s.apply(this);
00243 stmt2stmt.put(s, getResult());
00244 return (ca.mcgill.sable.util.List) getResult();
00245 }
00246 public String toString()
00247 {
00248 return "RS " + id;
00249 }
00250 }