Main Page   Packages   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

PredicateUpdate.java

00001 package edu.ksu.cis.bandera.specification.predicate;
00002 
00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00004  * Bandera, a Java(TM) analysis and transformation toolkit           *
00005  * Copyright (C) 2000   Robby (robby@cis.ksu.edu)                    *
00006  * All rights reserved.                                              *
00007  *                                                                   *
00008  * This work was done as a project in the SAnToS Laboratory,         *
00009  * Department of Computing and Information Sciences, Kansas State    *
00010  * University, USA (http://www.cis.ksu.edu/santos).                  *
00011  * It is understood that any modification not identified as such is  *
00012  * not covered by the preceding statement.                           *
00013  *                                                                   *
00014  * This work is free software; you can redistribute it and/or        *
00015  * modify it under the terms of the GNU Library General Public       *
00016  * License as published by the Free Software Foundation; either      *
00017  * version 2 of the License, or (at your option) any later version.  *
00018  *                                                                   *
00019  * This work is distributed in the hope that it will be useful,      *
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of    *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *
00022  * Library General Public License for more details.                  *
00023  *                                                                   *
00024  * You should have received a copy of the GNU Library General Public *
00025  * License along with this toolkit; if not, write to the             *
00026  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,      *
00027  * Boston, MA  02111-1307, USA.                                      *
00028  *                                                                   *
00029  * Java is a trademark of Sun Microsystems, Inc.                     *
00030  *                                                                   *
00031  * To submit a bug report, send a comment, or get the latest news on *
00032  * this project and other SAnToS projects, please visit the web-site *
00033  *                http://www.cis.ksu.edu/santos                      *
00034  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00035 import ca.mcgill.sable.soot.*;
00036 import edu.ksu.cis.bandera.jjjc.*;
00037 import edu.ksu.cis.bandera.annotation.*;
00038 import java.util.*;
00039 import ca.mcgill.sable.soot.grimp.*;
00040 import ca.mcgill.sable.soot.jimple.*;
00041 import edu.ksu.cis.bandera.jext.*;
00042 public class PredicateUpdate extends AbstractBanderaValueSwitch {
00043     private static PredicateUpdate pu = new PredicateUpdate();
00044     private static Grimp grimp = Grimp.v();
00045     private static Jimple jimple = Jimple.v();
00046     private static Stmt currentStmt;
00047     private Value currentValue;
00048 /**
00049  * caseAddExpr method comment.
00050  */
00051 public void caseAddExpr(AddExpr v) {
00052     v.getOp1().apply(this);
00053     Value v1 = currentValue;
00054     v.getOp2().apply(this);
00055     Value v2 = currentValue;
00056     currentValue = grimp.newAddExpr(v1, v2);
00057 }
00058 /**
00059  * caseAndExpr method comment.
00060  */
00061 public void caseAndExpr(AndExpr v) {
00062     v.getOp1().apply(this);
00063     Value v1 = currentValue;
00064     v.getOp2().apply(this);
00065     Value v2 = currentValue;
00066     currentValue = grimp.newAndExpr(v1, v2);
00067 }
00068 /**
00069  * caseArrayRef method comment.
00070  */
00071 public void caseArrayRef(ArrayRef v) {
00072     v.getBase().apply(this);
00073     Value base = currentValue;
00074     v.getIndex().apply(this);
00075     Value index = currentValue;
00076     currentValue = grimp.newArrayRef(base, index);
00077 }
00078 /**
00079  * caseCastExpr method comment.
00080  */
00081 public void caseCastExpr(CastExpr v) {
00082     v.getOp().apply(this);
00083     currentValue = grimp.newCastExpr(currentValue, v.getType());
00084 }
00085 /**
00086  * caseCaughtExceptionRef method comment.
00087  */
00088 public void caseCaughtExceptionRef(CaughtExceptionRef v) {
00089     defaultCase(v);
00090 }
00091 /**
00092  * caseChooseExpr method comment.
00093  */
00094 public void caseChooseExpr(ChooseExpr v) {
00095     Vector values = new Vector();
00096     for (ca.mcgill.sable.util.Iterator i = v.getChoices().iterator(); i.hasNext();) {
00097         ((Value) i.next()).apply(this);
00098         values.add(currentValue);
00099     }
00100     currentValue = new ChooseExpr(values);
00101 }
00102 /**
00103  * caseCmpExpr method comment.
00104  */
00105 public void caseCmpExpr(CmpExpr v) {
00106     v.getOp1().apply(this);
00107     Value v1 = currentValue;
00108     v.getOp2().apply(this);
00109     Value v2 = currentValue;
00110     currentValue = grimp.newCmpExpr(v1, v2);
00111 }
00112 /**
00113  * caseCmpgExpr method comment.
00114  */
00115 public void caseCmpgExpr(CmpgExpr v) {
00116     v.getOp1().apply(this);
00117     Value v1 = currentValue;
00118     v.getOp2().apply(this);
00119     Value v2 = currentValue;
00120     currentValue = grimp.newCmpgExpr(v1, v2);
00121 }
00122 /**
00123  * caseCmplExpr method comment.
00124  */
00125 public void caseCmplExpr(CmplExpr v) {
00126     v.getOp1().apply(this);
00127     Value v1 = currentValue;
00128     v.getOp2().apply(this);
00129     Value v2 = currentValue;
00130     currentValue = grimp.newCmplExpr(v1, v2);
00131 }
00132 /**
00133  * caseComplementExpr method comment.
00134  */
00135 public void caseComplementExpr(ComplementExpr expr) {
00136     expr.getOp().apply(this);
00137     currentValue = new ComplementExpr(currentValue);
00138 }
00139 /**
00140  * caseDivExpr method comment.
00141  */
00142 public void caseDivExpr(DivExpr v) {
00143     v.getOp1().apply(this);
00144     Value v1 = currentValue;
00145     v.getOp2().apply(this);
00146     Value v2 = currentValue;
00147     currentValue = grimp.newDivExpr(v1, v2);
00148 }
00149 /**
00150  * caseDoubleConstant method comment.
00151  */
00152 public void caseDoubleConstant(DoubleConstant v) {
00153     currentValue = DoubleConstant.v(v.value);
00154 }
00155 /**
00156  * caseEqExpr method comment.
00157  */
00158 public void caseEqExpr(EqExpr v) {
00159     v.getOp1().apply(this);
00160     Value v1 = currentValue;
00161     v.getOp2().apply(this);
00162     Value v2 = currentValue;
00163     currentValue = grimp.newEqExpr(v1, v2);
00164 }
00165 /**
00166  * caseFloatConstant method comment.
00167  */
00168 public void caseFloatConstant(FloatConstant v) {
00169     currentValue = FloatConstant.v(v.value);
00170 }
00171 /**
00172  * caseGeExpr method comment.
00173  */
00174 public void caseGeExpr(GeExpr v) {
00175     v.getOp1().apply(this);
00176     Value v1 = currentValue;
00177     v.getOp2().apply(this);
00178     Value v2 = currentValue;
00179     currentValue = grimp.newGeExpr(v1, v2);
00180 }
00181 /**
00182  * caseGtExpr method comment.
00183  */
00184 public void caseGtExpr(GtExpr v) {
00185     v.getOp1().apply(this);
00186     Value v1 = currentValue;
00187     v.getOp2().apply(this);
00188     Value v2 = currentValue;
00189     currentValue = grimp.newGtExpr(v1, v2);
00190 }
00191 /**
00192  * caseInExpr method comment.
00193  */
00194 public void caseInExpr(InExpr v) {
00195     v.getOp1().apply(this);
00196     Value v1 = currentValue;
00197 
00198     Vector values = new Vector();
00199     for (ca.mcgill.sable.util.Iterator i = v.getSet().iterator(); i.hasNext();) {
00200         ((Value) i.next()).apply(this);
00201         values.add(currentValue);
00202     }
00203     currentValue = new InExpr(v1, values);
00204 }
00205 /**
00206  * caseInstanceFieldRef method comment.
00207  */
00208 public void caseInstanceFieldRef(InstanceFieldRef v) {
00209     v.getBase().apply(this);
00210     currentValue = grimp.newInstanceFieldRef(currentValue, v.getField());
00211 }
00212 /**
00213  * caseInstanceOfExpr method comment.
00214  */
00215 public void caseInstanceOfExpr(InstanceOfExpr v) {
00216     v.getOp().apply(this);
00217     currentValue = grimp.newInstanceOfExpr(currentValue, v.getType());
00218 }
00219 /**
00220  * caseIntConstant method comment.
00221  */
00222 public void caseIntConstant(IntConstant v) {
00223     currentValue = IntConstant.v(v.value);
00224 }
00225 /**
00226  * caseInterfaceInvokeExpr method comment.
00227  */
00228 public void caseInterfaceInvokeExpr(InterfaceInvokeExpr v) {
00229     defaultCase(v);
00230 }
00231 /**
00232  * caseLeExpr method comment.
00233  */
00234 public void caseLeExpr(LeExpr v) {
00235     v.getOp1().apply(this);
00236     Value v1 = currentValue;
00237     v.getOp2().apply(this);
00238     Value v2 = currentValue;
00239     currentValue = grimp.newLeExpr(v1, v2);
00240 }
00241 /**
00242  * caseLengthExpr method comment.
00243  */
00244 public void caseLengthExpr(LengthExpr v) {
00245     v.getOp().apply(this);
00246     currentValue = grimp.newLengthExpr(currentValue);
00247 }
00248 /**
00249  * caseLocal method comment.
00250  */
00251 public void caseLocal(Local l) {
00252     defaultCase(l);
00253 }
00254 /**
00255  * caseLocalExpr method comment.
00256  */
00257 public void caseLocalExpr(LocalExpr v) {
00258     AnnotationManager am = CompilationManager.getAnnotationManager();
00259     HashSet locals = am.getInlinedLocal(v);
00260     Hashtable stmtLocalTable = am.getStmtLocalTable();
00261     HashSet stmtLocals = (HashSet) stmtLocalTable.get(currentStmt);
00262 
00263     for (Iterator i = locals.iterator(); i.hasNext();) {
00264         LocalExpr newV = (LocalExpr) i.next();
00265         if (stmtLocals.contains(newV)) {
00266             Hashtable localPackTable = am.getLocalPackingTable();
00267             if (localPackTable.get(newV) != null) {
00268                 currentValue = (Value) localPackTable.get(newV);
00269             } else {
00270                 currentValue = newV;
00271             }
00272             return;
00273         } 
00274     }
00275 
00276     System.out.println("*** WARNING: Can't find mapping to " + v + " ***");
00277 }
00278 /**
00279  * caseLocationTestExpr method comment.
00280  */
00281 public void caseLocationTestExpr(LocationTestExpr e) {
00282     defaultCase(e);
00283     //currentValue = new LocationTestExpr(stmts);
00284 }
00285 /**
00286  * caseLogicalAndExpr method comment.
00287  */
00288 public void caseLogicalAndExpr(LogicalAndExpr expr) {
00289     expr.getOp1().apply(this);
00290     Value v1 = currentValue;
00291     expr.getOp2().apply(this);
00292     Value v2 = currentValue;
00293     currentValue = new LogicalAndExpr(v1, v2);
00294 }
00295 /**
00296  * caseLogicalOrExpr method comment.
00297  */
00298 public void caseLogicalOrExpr(LogicalOrExpr expr) {
00299     expr.getOp1().apply(this);
00300     Value v1 = currentValue;
00301     expr.getOp2().apply(this);
00302     Value v2 = currentValue;
00303     currentValue = new LogicalOrExpr(v1, v2);
00304 }
00305 /**
00306  * caseLongConstant method comment.
00307  */
00308 public void caseLongConstant(LongConstant v) {
00309     currentValue = LongConstant.v(v.value);
00310 }
00311 /**
00312  * caseLtExpr method comment.
00313  */
00314 public void caseLtExpr(LtExpr v) {
00315     v.getOp1().apply(this);
00316     Value v1 = currentValue;
00317     v.getOp2().apply(this);
00318     Value v2 = currentValue;
00319     currentValue = grimp.newLtExpr(v1, v2);
00320 }
00321 /**
00322  * caseMulExpr method comment.
00323  */
00324 public void caseMulExpr(MulExpr v) {
00325     v.getOp1().apply(this);
00326     Value v1 = currentValue;
00327     v.getOp2().apply(this);
00328     Value v2 = currentValue;
00329     currentValue = grimp.newMulExpr(v1, v2);
00330 }
00331 /**
00332  * caseNeExpr method comment.
00333  */
00334 public void caseNeExpr(NeExpr v) {
00335     v.getOp1().apply(this);
00336     Value v1 = currentValue;
00337     v.getOp2().apply(this);
00338     Value v2 = currentValue;
00339     currentValue = grimp.newNeExpr(v1, v2);
00340 }
00341 /**
00342  * caseNegExpr method comment.
00343  */
00344 public void caseNegExpr(NegExpr v) {
00345     v.getOp().apply(this);
00346     currentValue = grimp.newNegExpr(currentValue);
00347 }
00348 /**
00349  * caseNewArrayExpr method comment.
00350  */
00351 public void caseNewArrayExpr(NewArrayExpr v) {
00352     defaultCase(v);
00353 }
00354 /**
00355  * caseNewExpr method comment.
00356  */
00357 public void caseNewExpr(NewExpr v) {
00358     defaultCase(v);
00359 }
00360 /**
00361  * caseNewInvokeExpr method comment.
00362  */
00363 public void caseNewInvokeExpr(NewInvokeExpr v) {
00364     defaultCase(v);
00365 }
00366 /**
00367  * caseNewMultiArrayExpr method comment.
00368  */
00369 public void caseNewMultiArrayExpr(NewMultiArrayExpr v) {
00370     defaultCase(v);
00371 }
00372 /**
00373  * caseNullConstant method comment.
00374  */
00375 public void caseNullConstant(NullConstant v) {
00376     currentValue = NullConstant.v();
00377 }
00378 /**
00379  * caseOrExpr method comment.
00380  */
00381 public void caseOrExpr(OrExpr v) {
00382     v.getOp1().apply(this);
00383     Value v1 = currentValue;
00384     v.getOp2().apply(this);
00385     Value v2 = currentValue;
00386     currentValue = grimp.newOrExpr(v1, v2);
00387 }
00388 /**
00389  * caseParameterRef method comment.
00390  */
00391 public void caseParameterRef(ParameterRef v) {
00392     defaultCase(v);
00393 }
00394 /**
00395  * caseRemExpr method comment.
00396  */
00397 public void caseRemExpr(RemExpr v) {
00398     v.getOp1().apply(this);
00399     Value v1 = currentValue;
00400     v.getOp2().apply(this);
00401     Value v2 = currentValue;
00402     currentValue = grimp.newRemExpr(v1, v2);
00403 }
00404 /**
00405  * caseShlExpr method comment.
00406  */
00407 public void caseShlExpr(ShlExpr v) {
00408     v.getOp1().apply(this);
00409     Value v1 = currentValue;
00410     v.getOp2().apply(this);
00411     Value v2 = currentValue;
00412     currentValue = grimp.newShlExpr(v1, v2);
00413 }
00414 /**
00415  * caseShrExpr method comment.
00416  */
00417 public void caseShrExpr(ShrExpr v) {
00418     v.getOp1().apply(this);
00419     Value v1 = currentValue;
00420     v.getOp2().apply(this);
00421     Value v2 = currentValue;
00422     currentValue = grimp.newShrExpr(v1, v2);
00423 }
00424 /**
00425  * caseSpecialInvokeExpr method comment.
00426  */
00427 public void caseSpecialInvokeExpr(SpecialInvokeExpr v) {
00428     defaultCase(v);
00429 }
00430 /**
00431  * caseStaticFieldRef method comment.
00432  */
00433 public void caseStaticFieldRef(StaticFieldRef v) {
00434     currentValue = grimp.newStaticFieldRef(v.getField());
00435 }
00436 /**
00437  * caseStaticInvokeExpr method comment.
00438  */
00439 public void caseStaticInvokeExpr(StaticInvokeExpr v) {
00440     defaultCase(v);
00441 }
00442 /**
00443  * caseStringConstant method comment.
00444  */
00445 public void caseStringConstant(StringConstant v) {
00446     currentValue = StringConstant.v(v.value);
00447 }
00448 /**
00449  * caseSubExpr method comment.
00450  */
00451 public void caseSubExpr(SubExpr v) {
00452     v.getOp1().apply(this);
00453     Value v1 = currentValue;
00454     v.getOp2().apply(this);
00455     Value v2 = currentValue;
00456     currentValue = grimp.newSubExpr(v1, v2);
00457 }
00458 /**
00459  * caseThisRef method comment.
00460  */
00461 public void caseThisRef(ThisRef v) {
00462     defaultCase(v);
00463 }
00464 /**
00465  * caseUshrExpr method comment.
00466  */
00467 public void caseUshrExpr(UshrExpr v) {
00468     v.getOp1().apply(this);
00469     Value v1 = currentValue;
00470     v.getOp2().apply(this);
00471     Value v2 = currentValue;
00472     currentValue = grimp.newUshrExpr(v1, v2);
00473 }
00474 /**
00475  * caseVirtualInvokeExpr method comment.
00476  */
00477 public void caseVirtualInvokeExpr(VirtualInvokeExpr v) {
00478     defaultCase(v);
00479 }
00480 /**
00481  * caseXorExpr method comment.
00482  */
00483 public void caseXorExpr(XorExpr v) {
00484     v.getOp1().apply(this);
00485     Value v1 = currentValue;
00486     v.getOp2().apply(this);
00487     Value v2 = currentValue;
00488     currentValue = grimp.newXorExpr(v1, v2);
00489 }
00490 /**
00491  * 
00492  * @return java.util.HashSet
00493  */
00494 private static HashSet getThreadMethods() {
00495     HashSet result = new HashSet();
00496     
00497     for (Enumeration e = CompilationManager.getCompiledClasses().elements(); e.hasMoreElements();) {
00498         SootClass sc = (SootClass) e.nextElement();
00499         if (sc.declaresMethod("main")) {
00500             result.add(sc.getMethod("main"));
00501         } else if (sc.declaresMethod("run")) {
00502             result.add(sc.getMethod("run"));
00503         }
00504     }
00505 
00506     return result;
00507 }
00508 /**
00509  * 
00510  * @return boolean
00511  * @param s java.util.Vector
00512  */
00513 private static boolean isInThreadBody(Stmt stmt) {
00514     Jimple jimple = Jimple.v();
00515     AnnotationManager am = CompilationManager.getAnnotationManager();
00516     
00517     HashSet stmtListSet = new HashSet();
00518     for (Iterator i = getThreadMethods().iterator(); i.hasNext();) {
00519         SootMethod sm = (SootMethod) i.next();
00520         stmtListSet.add(((JimpleBody) sm.getBody(jimple)).getStmtList());
00521     }
00522     
00523     for (Iterator j = stmtListSet.iterator(); j.hasNext();) {
00524         StmtList sl = (StmtList) j.next();
00525         if (sl.indexOf(stmt) >= 0) {
00526             return true;
00527         }
00528     }
00529 
00530     return false;
00531 }
00532 /**
00533  * 
00534  * @return ca.mcgill.sable.soot.jimple.Value
00535  * @param value ca.mcgill.sable.soot.jimple.Value
00536  */
00537 public static Value update(Value value) {
00538     if (value instanceof LogicalAndExpr) {
00539         if (((LogicalAndExpr) value).getOp1() instanceof LocationTestExpr) {
00540             AnnotationManager am = CompilationManager.getAnnotationManager();
00541             LocationTestExpr lte = (LocationTestExpr) ((LogicalAndExpr) value).getOp1();
00542             Value constraint = (Value) ((LogicalAndExpr) value).getOp2();
00543             Vector newStmts = new Vector();
00544             for (Iterator i = lte.getStmts().iterator(); i.hasNext();) {
00545                 Stmt stmt = (Stmt) i.next();
00546                 if (am.getReplacedStmt(stmt) != null)
00547                     stmt = am.getReplacedStmt(stmt);
00548                 if (am.getInlinedStmt(stmt) != null)
00549                     newStmts.addAll(am.getInlinedStmt(stmt));
00550                 else {
00551                     //System.out.println("*** WARNING : Can't update '" + value + "'");
00552                     throw new RuntimeException();
00553                 }
00554             }
00555             Vector result = new Vector();
00556             for (Iterator i = newStmts.iterator(); i.hasNext();) {
00557                 currentStmt = (Stmt) i.next();
00558                 if (isInThreadBody(currentStmt)) {
00559                     Vector v = new Vector();
00560                     v.add(currentStmt);
00561                     LocationTestExpr newLte = new LocationTestExpr(v);
00562                     pu.currentValue = null;
00563                     constraint.apply(pu);
00564                     result.add(new LogicalAndExpr(newLte, pu.currentValue));
00565                 }
00566             }
00567             Iterator i = result.iterator();
00568             value = (Value) i.next();
00569             while (i.hasNext()) {
00570                 value = new LogicalOrExpr(value, (Value) i.next());
00571             }
00572         }
00573     } else
00574         if (value instanceof LocationTestExpr) {
00575             AnnotationManager am = CompilationManager.getAnnotationManager();
00576             LocationTestExpr lte = (LocationTestExpr) value;
00577             Vector newStmts = new Vector();
00578             for (Iterator i = lte.getStmts().iterator(); i.hasNext();) {
00579                 Stmt stmt = (Stmt) i.next();
00580                 if (am.getReplacedStmt(stmt) != null)
00581                     stmt = am.getReplacedStmt(stmt);
00582                 if (am.getInlinedStmt(stmt) != null)
00583                     newStmts.addAll(am.getInlinedStmt(stmt));
00584                 else {
00585                     //System.out.println("*** WARNING : Can't update '" + value + "'");
00586                     throw new RuntimeException();
00587                 }
00588             }
00589             Vector result = new Vector();
00590             for (Iterator i = newStmts.iterator(); i.hasNext();) {
00591                 currentStmt = (Stmt) i.next();
00592                 if (isInThreadBody(currentStmt)) {
00593                     result.add(currentStmt);
00594                 }
00595             }
00596             value = new LocationTestExpr(result);
00597         }
00598     return value;
00599 }
00600 }

Generated at Thu Feb 7 06:52:44 2002 for Bandera by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001