00001 package edu.ksu.cis.bandera.jjjc.util;
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 import ca.mcgill.sable.soot.*;
00036 import ca.mcgill.sable.soot.jimple.*;
00037 import ca.mcgill.sable.util.*;
00038 import java.util.*;
00039 import ca.mcgill.sable.util.Iterator;
00040 import ca.mcgill.sable.util.LinkedList;
00041
00042 public class JimpleStmtCloner implements StmtSwitch {
00043 private static JimpleStmtCloner cloner = new JimpleStmtCloner();
00044 private static Jimple jimple = Jimple.v();
00045 private static Hashtable targets = new Hashtable();
00046 private static JimpleBody body;
00047 private Stmt result = null;
00048
00049
00050
00051 private JimpleStmtCloner() {
00052 }
00053
00054
00055
00056 public void caseAssignStmt(AssignStmt stmt) {
00057 result = jimple.newAssignStmt(JimpleValueCloner.clone(stmt.getLeftOp()),
00058 JimpleValueCloner.clone(stmt.getRightOp()));
00059 }
00060
00061
00062
00063 public void caseBreakpointStmt(BreakpointStmt stmt) {
00064 result = jimple.newBreakpointStmt();
00065 }
00066
00067
00068
00069 public void caseEnterMonitorStmt(EnterMonitorStmt stmt) {
00070 result = jimple.newEnterMonitorStmt(JimpleValueCloner.clone(stmt.getOp()));
00071 }
00072
00073
00074
00075 public void caseExitMonitorStmt(ExitMonitorStmt stmt) {
00076 result = jimple.newExitMonitorStmt(JimpleValueCloner.clone(stmt.getOp()));
00077 }
00078
00079
00080
00081 public void caseGotoStmt(GotoStmt stmt) {
00082 result = jimple.newGotoStmt(JimpleStmtCloner.clone((Stmt) stmt.getTarget()));
00083 }
00084
00085
00086
00087 public void caseIdentityStmt(IdentityStmt stmt) {
00088 result = jimple.newIdentityStmt(JimpleValueCloner.clone(stmt.getLeftOp()),
00089 JimpleValueCloner.clone(stmt.getRightOp()));
00090 }
00091
00092
00093
00094 public void caseIfStmt(IfStmt stmt) {
00095 result = jimple.newIfStmt(JimpleValueCloner.clone(stmt.getCondition()),
00096 JimpleStmtCloner.clone(stmt.getTarget()));
00097 }
00098
00099
00100
00101 public void caseInvokeStmt(InvokeStmt stmt) {
00102 result = jimple.newInvokeStmt(JimpleValueCloner.clone(stmt.getInvokeExpr()));
00103 }
00104
00105
00106
00107 public void caseLookupSwitchStmt(LookupSwitchStmt stmt) {
00108 Stmt defaultTarget = JimpleStmtCloner.clone((Stmt) stmt.getDefaultTarget());
00109 LinkedList newTargets = new LinkedList();
00110 LinkedList newValues = new LinkedList();
00111
00112 for (Iterator i = stmt.getTargets().iterator(); i.hasNext();) {
00113 newTargets.addLast(JimpleStmtCloner.clone((Stmt) i.next()));
00114 }
00115
00116 for (Iterator i = stmt.getLookupValues().iterator(); i.hasNext();) {
00117 newValues.addLast(JimpleValueCloner.clone((Value) i.next()));
00118 }
00119
00120 result = jimple.newLookupSwitchStmt(JimpleValueCloner.clone(stmt.getKey()), newValues,
00121 newTargets, defaultTarget);
00122 }
00123
00124
00125
00126 public void caseNopStmt(NopStmt stmt) {
00127 result = jimple.newNopStmt();
00128 }
00129
00130
00131
00132 public void caseRetStmt(RetStmt stmt) {
00133 result = jimple.newRetStmt(JimpleValueCloner.clone(stmt.getStmtAddress()));
00134 }
00135
00136
00137
00138 public void caseReturnStmt(ReturnStmt stmt) {
00139 result = jimple.newReturnStmt(JimpleValueCloner.clone(stmt.getReturnValue()));
00140 }
00141
00142
00143
00144 public void caseReturnVoidStmt(ReturnVoidStmt stmt) {
00145 result = jimple.newReturnVoidStmt();
00146 }
00147
00148
00149
00150 public void caseTableSwitchStmt(TableSwitchStmt stmt) {
00151 Stmt defaultTarget = JimpleStmtCloner.clone((Stmt) stmt.getDefaultTarget());
00152 LinkedList newTargets = new LinkedList();
00153
00154 for (Iterator i = stmt.getTargets().iterator(); i.hasNext();) {
00155 newTargets.addLast(JimpleStmtCloner.clone((Stmt) i.next()));
00156 }
00157
00158 result = jimple.newTableSwitchStmt(JimpleValueCloner.clone(stmt.getKey()), stmt.getLowIndex(),
00159 stmt.getHighIndex(), newTargets, defaultTarget);
00160 }
00161
00162
00163
00164 public void caseThrowStmt(ThrowStmt stmt) {
00165 result = jimple.newThrowStmt(JimpleValueCloner.clone(stmt.getOp()));
00166 }
00167
00168
00169
00170
00171
00172 public static Stmt clone(Stmt stmt) {
00173 if (targets.get(stmt) != null) return (Stmt) targets.get(stmt);
00174
00175 stmt.apply(cloner);
00176 Stmt result = cloner.getResult();
00177 targets.put(stmt, result);
00178
00179 return result;
00180 }
00181
00182
00183
00184
00185 public static void copyTrap(JimpleBody body) {
00186 for (Iterator i = body.getTraps().iterator(); i.hasNext();) {
00187 JTrap trap = (JTrap) i.next();
00188 Stmt begin = (Stmt) targets.get(trap.getBeginUnit());
00189 Stmt end = (Stmt) targets.get(trap.getEndUnit());
00190 Stmt handler = (Stmt) targets.get(trap.getHandlerUnit());
00191 if ((begin != null) && (end != null) && (handler != null)) {
00192 JimpleStmtCloner.body.addTrap(jimple.newTrap(trap.getException(), begin, end, handler));
00193 }
00194 }
00195 }
00196
00197
00198
00199 public void defaultCase(Object obj) {
00200 result = null;
00201 }
00202
00203
00204
00205
00206 private Stmt getResult() {
00207 return result;
00208 }
00209
00210
00211
00212 public static void reset() {
00213 targets = new Hashtable();
00214 }
00215
00216
00217
00218
00219 public static void setBody(JimpleBody b) {
00220 body = b;
00221 JimpleValueCloner.setBody(b);
00222 }
00223 }