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

PredicateProcessor.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 edu.ksu.cis.bandera.annotation.*;
00036 import edu.ksu.cis.bandera.jjjc.*;
00037 import edu.ksu.cis.bandera.jjjc.symboltable.*;
00038 import ca.mcgill.sable.soot.*;
00039 import ca.mcgill.sable.soot.grimp.*;
00040 import ca.mcgill.sable.soot.jimple.*;
00041 import edu.ksu.cis.bandera.jext.*;
00042 import edu.ksu.cis.bandera.jjjc.util.*;
00043 import edu.ksu.cis.bandera.specification.predicate.datastructure.*;
00044 import edu.ksu.cis.bandera.specification.predicate.analysis.*;
00045 import edu.ksu.cis.bandera.specification.predicate.node.*;
00046 import java.util.*;
00047 public class PredicateProcessor extends DepthFirstAdapter {
00048     private static Grimp grimp = Grimp.v();
00049     private static Jimple jimple = Jimple.v();
00050     private static Value ph;
00051     private static Hashtable phParams;
00052     private Value currentValue;
00053     private Vector constraintValues = new Vector();
00054     private static Hashtable variablesUsed;
00055     private static SootMethod sm;
00056 /**
00057  * 
00058  * @param node edu.ksu.cis.bandera.predicate.node.ABinaryExp
00059  */
00060 public void caseABinaryExp(ABinaryExp node) {
00061     node.getLeft().apply(this);
00062     Value leftValue = currentValue;
00063     node.getRight().apply(this);
00064     
00065     PBinOp op = node.getBinOp();
00066     if (op instanceof AEqualBinOp) {
00067         currentValue = grimp.newEqExpr(leftValue, currentValue);
00068     } else if (op instanceof ANotEqualBinOp) {
00069         currentValue = grimp.newNeExpr(leftValue, currentValue);
00070     } else if (op instanceof ALessBinOp) {
00071         currentValue = grimp.newLtExpr(leftValue, currentValue);
00072     } else if (op instanceof ALessEqualBinOp) {
00073         currentValue = grimp.newLeExpr(leftValue, currentValue);
00074     } else if (op instanceof AGreaterBinOp) {
00075         currentValue = grimp.newGtExpr(leftValue, currentValue);
00076     } else if (op instanceof AGreaterEqualBinOp) {
00077         currentValue = grimp.newGeExpr(leftValue, currentValue);
00078     } else if (op instanceof AAndBinOp) {
00079         currentValue = new LogicalAndExpr(leftValue, currentValue);
00080     } else if (op instanceof AOrBinOp) {
00081         currentValue = new LogicalOrExpr(leftValue, currentValue);
00082     } else if (op instanceof APlusBinOp) {
00083         currentValue = grimp.newAddExpr(leftValue, currentValue);
00084     } else if (op instanceof AMinusBinOp) {
00085         currentValue = grimp.newSubExpr(leftValue, currentValue);
00086     } else if (op instanceof ATimesBinOp) {
00087         currentValue = grimp.newMulExpr(leftValue, currentValue);
00088     } else if (op instanceof AShiftLeftBinOp) {
00089         currentValue = grimp.newShlExpr(leftValue, currentValue);
00090     } else if (op instanceof ASignedShiftRightBinOp) {
00091         currentValue = grimp.newShrExpr(leftValue, currentValue);
00092     } else if (op instanceof AUnsignedShiftRightBinOp) {
00093         currentValue = grimp.newUshrExpr(leftValue, currentValue);
00094     } else if (op instanceof ABitAndBinOp) {
00095         currentValue = grimp.newAndExpr(leftValue, currentValue);
00096     } else if (op instanceof ABitOrBinOp) {
00097         currentValue = grimp.newOrExpr(leftValue, currentValue);
00098     } else if (op instanceof ABitXorBinOp) {
00099         currentValue = grimp.newXorExpr(leftValue, currentValue);
00100     } else if (op instanceof AStrongDivBinOp) {
00101         constraintValues.add(grimp.newNeExpr(currentValue, IntConstant.v(0)));
00102         currentValue = grimp.newDivExpr(leftValue, currentValue);
00103     } else if (op instanceof AStrongModBinOp) {
00104         constraintValues.add(grimp.newNeExpr(currentValue, IntConstant.v(0)));
00105         currentValue = grimp.newRemExpr(leftValue, currentValue);
00106     } 
00107 }
00108 /**
00109  * 
00110  * @param node edu.ksu.cis.bandera.predicate.node.ABitComplementExp
00111  */
00112 public void caseABitComplementExp(ABitComplementExp node) {
00113     node.getExp().apply(this);
00114     if (currentValue.getType() instanceof ca.mcgill.sable.soot.LongType) {
00115         currentValue = grimp.newXorExpr(currentValue, LongConstant.v(-1));
00116     } else {
00117         currentValue = grimp.newXorExpr(currentValue, IntConstant.v(-1));
00118     }
00119 }
00120 /**
00121  * 
00122  * @param node edu.ksu.cis.bandera.predicate.node.ACharLiteral
00123  */
00124 public void caseACharLiteral(ACharLiteral node) {
00125     String literal = node.toString().trim();
00126     literal = literal.substring(1, literal.length() - 1);
00127     int value = 0;
00128 
00129     if (literal.startsWith("\\")) {
00130         switch (literal.charAt(1)) {
00131             case 'b': value = '\b';
00132                 break;
00133             case 't': value = '\t';
00134                 break;
00135             case 'n': value = '\n';
00136                 break;
00137             case 'f': value = '\f';
00138                 break;
00139             case 'r': value = '\r';
00140                 break;
00141             case '\"': value = '\"';
00142                 break;
00143             case '\'': value = '\'';
00144                 break;
00145             case '\\': value = '\\';
00146                 break;
00147             default: value = Integer.valueOf(literal.substring(1), 8).intValue();
00148         }
00149     } else if (literal.startsWith("\\u")) {
00150         value = Integer.valueOf(literal.substring(2), 16).intValue();
00151     } else value = literal.charAt(0);
00152     
00153     currentValue = IntConstant.v(value);
00154 }
00155 /**
00156  * 
00157  * @param node edu.ksu.cis.bandera.predicate.node.AComplementExp
00158  */
00159 public void caseAComplementExp(AComplementExp node) {
00160     node.getExp().apply(this);
00161     currentValue = new ComplementExpr(currentValue);
00162 }
00163 /**
00164  * 
00165  * @param node edu.ksu.cis.bandera.predicate.node.ADecIntLiteral
00166  */
00167 public void caseADecIntLiteral(ADecIntLiteral node) {
00168     currentValue = IntConstant.v(Integer.parseInt(node.toString().trim()));
00169 }
00170 /**
00171  * 
00172  * @param node edu.ksu.cis.bandera.predicate.node.ADecLongLiteral
00173  */
00174 public void caseADecLongLiteral(ADecLongLiteral node) {
00175     String literal = node.toString().trim();
00176     literal = literal.substring(0, literal.length() - 1);
00177     currentValue = LongConstant.v(Long.parseLong(literal));
00178 }
00179 /**
00180  * 
00181  * @param node edu.ksu.cis.bandera.predicate.node.ADoubleLiteral
00182  */
00183 public void caseADoubleLiteral(ADoubleLiteral node) {
00184     currentValue = DoubleConstant.v(Double.valueOf(node.toString().trim()).floatValue());
00185 }
00186 /**
00187  * 
00188  * @param node edu.ksu.cis.bandera.predicate.node.AFalseLiteral
00189  */
00190 public void caseAFalseLiteral(AFalseLiteral node) {
00191     currentValue = IntConstant.v(0);
00192 }
00193 /**
00194  * 
00195  * @param node edu.ksu.cis.bandera.predicate.node.AFloatLiteral
00196  */
00197 public void caseAFloatLiteral(AFloatLiteral node) {
00198     currentValue = FloatConstant.v(Float.valueOf(node.toString().trim()).floatValue());
00199 }
00200 /**
00201  * 
00202  * @param node edu.ksu.cis.bandera.predicate.node.AHexIntLiteral
00203  */
00204 public void caseAHexIntLiteral(AHexIntLiteral node) {
00205     currentValue = IntConstant.v(Integer.parseInt(node.toString().trim(), 16));
00206 }
00207 /**
00208  * 
00209  * @param node edu.ksu.cis.bandera.predicate.node.AHexLongLiteral
00210  */
00211 public void caseAHexLongLiteral(AHexLongLiteral node) {
00212     String literal = node.toString().substring(2).trim();
00213     literal = literal.substring(0, literal.length() - 1);
00214     currentValue = LongConstant.v(Long.parseLong(literal, 16));
00215 }
00216 /**
00217  * 
00218  * @param node edu.ksu.cis.bandera.predicate.node.AInstanceofExp
00219  */
00220 public void caseAInstanceofExp(AInstanceofExp node) {
00221     node.getExp().apply(this);
00222     currentValue = grimp.newInstanceOfExpr(currentValue, RefType.v(new Name(node.toString()).toString()));
00223 }
00224 /**
00225  * 
00226  * @param node edu.ksu.cis.bandera.predicate.node.ANameExp
00227  */
00228 public void caseANameExp(ANameExp node) {
00229     Object o = variablesUsed.get(node);
00230     if (o instanceof String) {
00231         currentValue = (Value) phParams.get(o);
00232     } else if (o instanceof Local) {
00233         currentValue = new LocalExpr(sm, (Local) o);
00234     } else if (o instanceof Field) {
00235         Field f = (Field) variablesUsed.get(node);
00236         try {
00237             SootClass sc = CompilationManager.getSootClassManager().getClass(f.getDeclaringClassOrInterface().toString());
00238             SootField sf = sc.getField(f.getName().toString());
00239             if (Modifier.isStatic(sf.getModifiers()))
00240                 currentValue = grimp.newStaticFieldRef(sf);
00241             else 
00242                 currentValue = grimp.newInstanceFieldRef(ph, sf);
00243         } catch (Exception e) {
00244             throw new RuntimeException("Unexpected error: " + e);
00245         }
00246     }
00247 }
00248 /**
00249  * 
00250  * @param node edu.ksu.cis.bandera.predicate.node.ANegativeExp
00251  */
00252 public void caseANegativeExp(ANegativeExp node) {
00253     node.getExp().apply(this);
00254     currentValue = grimp.newNegExpr(currentValue);
00255 }
00256 /**
00257  * 
00258  * @param node edu.ksu.cis.bandera.predicate.node.ANullLiteral
00259  */
00260 public void caseANullLiteral(ANullLiteral node) {
00261     currentValue = NullConstant.v();
00262 }
00263 /**
00264  * 
00265  * @param node edu.ksu.cis.bandera.predicate.node.AOctIntLiteral
00266  */
00267 public void caseAOctIntLiteral(AOctIntLiteral node) {
00268     currentValue = IntConstant.v(Integer.parseInt(node.toString().trim(), 8));
00269 }
00270 /**
00271  * 
00272  * @param node edu.ksu.cis.bandera.predicate.node.AOctLongLiteral
00273  */
00274 public void caseAOctLongLiteral(AOctLongLiteral node) {
00275     String literal = node.toString().substring(1).trim();
00276     literal = literal.substring(0, literal.length() - 1);
00277     currentValue = LongConstant.v(Long.parseLong(literal, 8));
00278 }
00279 /**
00280  * 
00281  * @param node edu.ksu.cis.bandera.predicate.node.AQuestionExp
00282  */
00283 public void caseAQuestionExp(AQuestionExp node) {
00284     node.getExp().apply(this);
00285     Value conditionValue = currentValue;
00286     node.getTrueExp().apply(this);
00287     Value trueValue = currentValue;
00288     node.getFalseExp().apply(this);
00289     currentValue = new LogicalOrExpr(new LogicalAndExpr(conditionValue, trueValue),
00290             new LogicalAndExpr(new ComplementExpr(conditionValue), currentValue)); 
00291 }
00292 /**
00293  * 
00294  * @param node edu.ksu.cis.bandera.predicate.node.AReturnValueExp
00295  */
00296 public void caseAReturnValueExp(AReturnValueExp node) {
00297     currentValue = new LocalExpr(sm, ((JimpleBody) sm.getBody(Jimple.v())).getLocal("$ret"));
00298 }
00299 /**
00300  * 
00301  * @param node edu.ksu.cis.bandera.predicate.node.AStringLiteral
00302  */
00303 public void caseAStringLiteral(AStringLiteral node) {
00304     currentValue = StringConstant.v(Util.decodeString(node.toString().trim()));
00305 }
00306 /**
00307  * 
00308  * @param node edu.ksu.cis.bandera.predicate.node.AStrongArrayNavigation
00309  */
00310 public void caseAStrongArrayNavigation(AStrongArrayNavigation node) {
00311     Value baseValue = currentValue;
00312     node.getExp().apply(this);
00313 
00314     constraintValues.add(grimp.newNeExpr(baseValue, NullConstant.v()));
00315     constraintValues.add(grimp.newGeExpr(currentValue, IntConstant.v(0)));
00316     constraintValues.add(grimp.newLtExpr(currentValue, grimp.newLengthExpr(baseValue)));
00317 
00318     currentValue = grimp.newArrayRef(baseValue, currentValue);
00319 }
00320 /**
00321  * 
00322  * @param node edu.ksu.cis.bandera.predicate.node.AStrongCastExp
00323  */
00324 public void caseAStrongCastExp(AStrongCastExp node) {
00325     ca.mcgill.sable.soot.Type type = Util.convertType((edu.ksu.cis.bandera.jjjc.symboltable.Type) variablesUsed.get(node));
00326     node.getExp().apply(this);
00327 
00328     constraintValues.add(grimp.newInstanceOfExpr(currentValue, type));
00329     
00330     currentValue = grimp.newCastExpr(currentValue, type);
00331 }
00332 /**
00333  * 
00334  * @param node edu.ksu.cis.bandera.predicate.node.AStrongObjectNavigation
00335  */
00336 public void caseAStrongObjectNavigation(AStrongObjectNavigation node) {
00337     constraintValues.add(grimp.newNeExpr(currentValue, NullConstant.v()));
00338     Hashtable vu = variablesUsed;
00339     Field f = (Field) vu.get(node);
00340     try {
00341         SootClass sc = CompilationManager.getSootClassManager().getClass(f.getDeclaringClassOrInterface().toString());
00342         SootField sf = sc.getField(f.getName().toString());
00343         if (Modifier.isStatic(sf.getModifiers()))
00344             currentValue = grimp.newStaticFieldRef(sf);
00345         else 
00346             currentValue = grimp.newInstanceFieldRef(currentValue, sf);
00347     } catch (Exception e) {
00348         throw new RuntimeException("Unexpected error: " + e);
00349     }
00350 }
00351 /**
00352  * 
00353  * @param node edu.ksu.cis.bandera.predicate.node.AThisExp
00354  */
00355 public void caseAThisExp(AThisExp node) {
00356     currentValue = ph;
00357 }
00358 /**
00359  * 
00360  * @param node edu.ksu.cis.bandera.predicate.node.ATrueLiteral
00361  */
00362 public void caseATrueLiteral(ATrueLiteral node) {
00363     currentValue = IntConstant.v(1);
00364 }
00365 /**
00366  * 
00367  * @return ca.mcgill.sable.soot.jimple.Value
00368  * @param placeHolder ca.mcgill.sable.soot.jimple.Value
00369  * @param placeHolderParams java.util.Hashtable
00370  * @param p edu.ksu.cis.bandera.predicate.datastructure.Predicate
00371  */
00372 public static Value process(Value placeHolder, Hashtable placeHolderParams, Predicate p) {
00373     ph = placeHolder;
00374     phParams = placeHolderParams;
00375     variablesUsed = p.getVariablesUsed();
00376     
00377     if (p.getAnnotation() != null) {
00378         Annotation a = p.getAnnotation();
00379         if (a instanceof LabeledStmtAnnotation) {
00380             a = CompilationManager.getAnnotationManager().getMethodAnnotationContainingAnnotation(a);
00381         }
00382         sm = (a instanceof MethodDeclarationAnnotation) ?
00383                 ((MethodDeclarationAnnotation) a).getSootMethod() :
00384                 ((ConstructorDeclarationAnnotation) a).getSootMethod();
00385     }
00386     
00387     Value constraintValue = null;
00388     if (p.getConstraint() != null) {
00389         PredicateProcessor pp = new PredicateProcessor();
00390         p.getConstraint().apply(pp);
00391         constraintValue = pp.currentValue;
00392         Object[] constraints = pp.constraintValues.toArray();
00393         for (int i = constraints.length - 1; i >= 0; i--) {
00394             constraintValue = new LogicalAndExpr((Value) constraints[i], constraintValue);
00395         }
00396     }
00397 
00398     if (p instanceof ExpressionPredicate) return constraintValue;
00399     Vector v = new Vector();
00400     if (p instanceof ReturnPredicate) {
00401         ReturnPredicate rp = (ReturnPredicate) p;
00402         Object[] stmts = ((JimpleBody) sm.getBody(Jimple.v())).getStmtList().toArray();
00403         for (int i = 0; i < stmts.length; i++) {
00404             if ((stmts[i] instanceof ReturnStmt) || (stmts[i] instanceof ReturnVoidStmt)) {
00405                 v.add(stmts[i]);
00406             }
00407         }
00408     } else if (p instanceof InvokePredicate) {
00409         Object[] stmts = ((JimpleBody) sm.getBody(Jimple.v())).getStmtList().toArray();
00410         for (int i = 0; i < stmts.length; i++) {
00411             if (!(stmts[i] instanceof IdentityStmt)) {
00412                 v.add(stmts[i]);
00413                 break;
00414             }
00415         }
00416     } else {
00417         v.add(p.getAnnotation().getStatements()[0]);
00418     }
00419     if (constraintValue != null) {
00420         Value result = constraintValue;
00421         if (ph != null) {
00422             Value temp = grimp.newEqExpr(ph, new LocalExpr(sm, ((JimpleBody) sm.getBody(jimple)).getLocal("JJJCTEMP$0")));
00423             result = new LogicalAndExpr(result, temp);
00424         }
00425         return new LogicalAndExpr(new LocationTestExpr(v), result);
00426     } else {
00427         Value result = new LocationTestExpr(v);
00428         if (ph != null) {
00429             Value temp = grimp.newEqExpr(ph, new LocalExpr(sm, ((JimpleBody) sm.getBody(jimple)).getLocal("JJJCTEMP$0")));
00430             result = new LogicalAndExpr(result, temp);
00431         }
00432         return result;
00433     }
00434 }
00435 }

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