00001 package edu.ksu.cis.bandera.pdgslicer;
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
00037 import ca.mcgill.sable.soot.jimple.*;
00038 import ca.mcgill.sable.soot.*;
00039 import ca.mcgill.sable.util.*;
00040 import edu.ksu.cis.bandera.pdgslicer.exceptions.*;
00041
00042
00043
00044
00045 public class Fields {
00046
00047
00048
00049
00050
00051 Set staticFields;
00052
00053
00054
00055
00056 Set instanceFields;
00057
00058
00059
00060
00061
00062 Set paraFields;
00063
00064
00065
00066
00067 Set otherInsFds;
00068
00069
00070
00071
00072
00073
00074 public Fields()
00075 {
00076 staticFields = null;
00077 instanceFields = null;
00078 paraFields = null;
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 static int getParaIndex(InstanceFieldRef insFieldRef, Local[] paraLocals, SimpleLocalCopies simpleLocalCopiesInCalledMd, Stmt interStmt) {
00098
00099 Value base = insFieldRef.getBase();
00100 if (!(base instanceof Local))
00101 throw new BaseValueNonLocalException("parameter instance field reference should be local variable");
00102 Local paraLocal = (Local) base;
00103 int paraIndex = -1;
00104
00105
00106 for (int j = 0; j < paraLocals.length; j++) {
00107 if (paraLocal.equals(paraLocals[j])) {
00108 paraIndex = j;
00109 break;
00110 } else
00111 if (simpleLocalCopiesInCalledMd.isLocalCopyOfBefore(paraLocal, paraLocals[j], interStmt)) {
00112 paraIndex = j;
00113 break;
00114 }
00115 }
00116 if (paraIndex == -1)
00117 throw new NoParaFieldFoundException("Parameter instance field reference should be found in the paraLocals array");
00118 return paraIndex;
00119 }
00120
00121
00122
00123
00124
00125
00126 static boolean isThisRef(SootMethod enclosingMethod, Value base, Stmt thisRefStmt) {
00127 if (thisRefStmt==null) return false;
00128 Set refSet = Slicer.BOFA_Analysis.referenceValueSet(base, enclosingMethod);
00129 if (refSet.contains(thisRefStmt))
00130 return true;
00131 return false;
00132 }
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 public void merge(Fields fields, CallSite site, MethodInfo methodInfo, MethodInfo calledMdInfo) {
00143
00144
00145 Set newStaticFields = new ArraySet();
00146 Set staticFdInCalledMd = fields.staticFields;
00147 for (Iterator i = staticFdInCalledMd.iterator(); i.hasNext();) {
00148 DataBox dbx = (DataBox) i.next();
00149 Set staticFdSet = dbx.getInterferVars();
00150 DataBox newdbx = new DataBox(site.callStmt, staticFdSet);
00151 if (!this.staticFields.contains(newdbx))
00152 newStaticFields.add(newdbx);
00153 }
00154 this.staticFields.addAll(newStaticFields);
00155 Set newInstanceFields = new ArraySet();
00156 newInstanceFields.addAll(this.instanceFields);
00157
00158
00159
00160
00161
00162
00163 Value base = null;
00164 NonStaticInvokeExpr nonStaticInvokeExpr = null;
00165 boolean nonStaticInvoke = false;
00166 InvokeExpr invokeExpr = site.invokeExpr;
00167 if (invokeExpr instanceof NonStaticInvokeExpr) {
00168 nonStaticInvokeExpr = (NonStaticInvokeExpr) invokeExpr;
00169 base = nonStaticInvokeExpr.getBase();
00170 nonStaticInvoke = true;
00171 } else {
00172
00173 }
00174 Set insFdAtCallSite = new ArraySet();
00175 if (nonStaticInvoke) {
00176
00177
00178
00179 Set insFdInCallee = fields.instanceFields;
00180 for (Iterator i = insFdInCallee.iterator(); i.hasNext();) {
00181 DataBox insFdBox = (DataBox) i.next();
00182 Set insFields = insFdBox.getInterferVars();
00183 insFdAtCallSite.addAll(BuildPDG.cloneAndChangeBase(insFields, base));
00184 }
00185 }
00186 this.instanceFields = newInstanceFields;
00187 Set newParaFields = new ArraySet();
00188 newParaFields.addAll(this.paraFields);
00189 Set paraFieldsAtThisSite = new ArraySet();
00190 Set otherInsFdAtThisSite = new ArraySet();
00191 Set newOtherInsFd = new ArraySet();
00192 newOtherInsFd.addAll(this.otherInsFds);
00193
00194
00195
00196 if (insFdAtCallSite != null) {
00197 for (Iterator i = insFdAtCallSite.iterator(); i.hasNext();) {
00198 InstanceFieldRef insFd = (InstanceFieldRef) i.next();
00199 if (methodInfo.indexMaps.isParaField(insFd, site.callStmt))
00200 paraFieldsAtThisSite.add(insFd);
00201 }
00202 }
00203 Set paraFieldsAfterChangeBase = parametersLocalize(calledMdInfo, fields, invokeExpr);
00204
00205
00206
00207 for (Iterator jj = paraFieldsAfterChangeBase.iterator(); jj.hasNext();) {
00208 InstanceFieldRef paraFieldCalled = (InstanceFieldRef) jj.next();
00209 if (methodInfo.indexMaps.isParaField(paraFieldCalled, site.callStmt))
00210 paraFieldsAtThisSite.add(paraFieldCalled);
00211 else
00212 if (Fields.isThisRef(methodInfo.sootMethod, paraFieldCalled.getBase(), methodInfo.indexMaps.getThisRefStmt()))
00213 insFdAtCallSite.add(paraFieldCalled);
00214 else
00215 otherInsFdAtThisSite.add(paraFieldCalled);
00216 }
00217 if (paraFieldsAtThisSite.size() != 0) {
00218 DataBox newdbx = new DataBox(site.callStmt, paraFieldsAtThisSite);
00219 newParaFields.add(newdbx);
00220 }
00221 this.paraFields = newParaFields;
00222 if (!insFdAtCallSite.isEmpty()) {
00223 DataBox newdbx = new DataBox(site.callStmt, insFdAtCallSite);
00224 newInstanceFields.add(newdbx);
00225 }
00226 this.instanceFields = newInstanceFields;
00227 if (!otherInsFdAtThisSite.isEmpty()) {
00228 DataBox newdbx = new DataBox(site.callStmt, otherInsFdAtThisSite);
00229 newOtherInsFd.add(newdbx);
00230 }
00231 this.otherInsFds = newOtherInsFd;
00232 }
00233 public boolean noFieldsInMethod()
00234 {
00235 return (staticFields.size()==0 && instanceFields.size()==0 &&
00236 paraFields.size() == 0 );
00237
00238 }
00239 public boolean noInstanceFieldsInMethod()
00240 {
00241 return instanceFields.size()==0;
00242 }
00243 public boolean noParaFields()
00244 {
00245 return paraFields.size() == 0;
00246 }
00247 public boolean noStaticFieldsInMethod()
00248 {
00249 return staticFields.size()==0;
00250 }
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267 static Set parametersLocalize(MethodInfo calledMdInfo, Fields fields, InvokeExpr invokeExpr) {
00268 SimpleLocalCopies simpleLocalCopiesInCalledMd = new SimpleLocalCopies((CompleteStmtGraph) calledMdInfo.indexMaps.getStmtGraph());
00269 Local paraLocals[] = calledMdInfo.indexMaps.getParaLocalSet();
00270 Set paraFieldsInCalledMd = fields.paraFields;
00271 Set paraFieldsAfterChangeBase = new ArraySet();
00272 for (Iterator i = paraFieldsInCalledMd.iterator(); i.hasNext();) {
00273 DataBox insFieldRefBox = (DataBox) i.next();
00274 Set insFieldRefs = insFieldRefBox.getInterferVars();
00275 for (Iterator k = insFieldRefs.iterator(); k.hasNext();) {
00276 Object element = (Object) k.next();
00277 if (element instanceof Local)
00278 continue;
00279 InstanceFieldRef insFieldRef = (InstanceFieldRef) element;
00280
00281
00282 int paraIndex = getParaIndex(insFieldRef, paraLocals, simpleLocalCopiesInCalledMd, insFieldRefBox.getInterferStmt());
00283 InstanceFieldRef newInsFieldRef = Jimple.v().newInstanceFieldRef(invokeExpr.getArg(paraIndex), insFieldRef.getField());
00284 paraFieldsAfterChangeBase.add(newInsFieldRef);
00285 }
00286 }
00287 return paraFieldsAfterChangeBase;
00288 }
00289 public String toString()
00290 {
00291 return "\nStaticFields: " + staticFields + "\n" +
00292 "instanceFields: " + instanceFields + "\n" +
00293 "paraFields: " + paraFields;
00294 }
00295 }