00001 package edu.ksu.cis.bandera.abstraction;
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.grimp.*;
00038 import ca.mcgill.sable.soot.jimple.*;
00039 import edu.ksu.cis.bandera.jext.*;
00040 import edu.ksu.cis.bandera.abstraction.typeinference.*;
00041 import edu.ksu.cis.bandera.abstraction.util.*;
00042 import java.util.*;
00043 public class PredicateAbstractor extends AbstractBanderaValueSwitch {
00044 private static Grimp grimp = Grimp.v();
00045 private PredicateInterpreter pi = new PredicateInterpreter();
00046 private TypeTable typeTable;
00047 private Hashtable variableSetTable;
00048 private TypeTable coercedTypeTable;
00049
00050
00051
00052
00053
00054 public PredicateAbstractor(TypeTable typeTable, Hashtable varSetTable) {
00055 this.typeTable = typeTable;
00056 this.variableSetTable = varSetTable;
00057 }
00058
00059
00060
00061
00062 public static Value abs(CoercionManager cm, TypeTable typeTable, Value v) {
00063 if (typeTable.size() == 0) return v;
00064 Hashtable varSetTable = new Hashtable();
00065 PredicateTypeChecker.check(cm, typeTable, v, varSetTable);
00066 PredicateAbstractor pa = new PredicateAbstractor(typeTable, varSetTable);
00067 v.apply(pa);
00068 return (Value) pa.getResult();
00069 }
00070
00071
00072
00073
00074 public void caseComplementExpr(ComplementExpr expr) {
00075 expr.getOp().apply(this);
00076 expr.setOp((Value) getResult());
00077 setResult(expr);
00078 }
00079
00080
00081
00082
00083 public void caseLocationTestExpr(LocationTestExpr e) {
00084 defaultCase(e);
00085 }
00086
00087
00088
00089
00090 public void caseLogicalAndExpr(LogicalAndExpr expr) {
00091 expr.getOp1().apply(this);
00092 expr.setOp1((Value) getResult());
00093 expr.getOp2().apply(this);
00094 expr.setOp2((Value) getResult());
00095 setResult(expr);
00096 }
00097
00098
00099
00100
00101 public void caseLogicalOrExpr(LogicalOrExpr expr) {
00102 expr.getOp1().apply(this);
00103 expr.setOp1((Value) getResult());
00104 expr.getOp2().apply(this);
00105 expr.setOp2((Value) getResult());
00106 setResult(expr);
00107 }
00108
00109
00110
00111
00112 public void defaultCase(Object o) {
00113 Value v = (Value) o;
00114 Abstraction a = typeTable.get(v);
00115 if (!((a instanceof RealAbstraction) && !(a instanceof ConcreteRealAbstraction)) && !((a instanceof IntegralAbstraction) && !(a instanceof ConcreteIntegralAbstraction))) {
00116 setResult(v);
00117 return;
00118 }
00119 Vector variables = new Vector();
00120 for (Iterator i = ((Set) variableSetTable.get(v)).iterator(); i.hasNext();) {
00121 Value var = (Value) i.next();
00122 if (var.getType() instanceof BaseType)
00123 variables.add(var);
00124 }
00125 int size = variables.size();
00126 int[] absNumOfTokens = new int[size];
00127 int numOfPossibleTokens = 1;
00128 for (int i = 0; i < size; i++) {
00129 a = typeTable.get(variables.elementAt(i));
00130 absNumOfTokens[i] = ((Integer) AbstractionClassLoader.invokeMethod(a.getClass().getName(), "getNumOfTokens", new Class[0], null, new Object[0])).intValue();
00131 numOfPossibleTokens *= absNumOfTokens[i];
00132 }
00133 int[] changes = new int[size];
00134 for (int i = size - 1, change = 1; i >= 0; change *= absNumOfTokens[i], i--) {
00135 changes[i] = change;
00136 }
00137 int tokens[] = new int[size];
00138 int token[] = new int[size];
00139 Value result = null;
00140 for (int i = 0; i < numOfPossibleTokens; i++) {
00141 for (int j = 0; j < size; j++) {
00142 token[j] = (i / changes[j]) % absNumOfTokens[j];
00143 tokens[j] = 1 << token[j];
00144 }
00145 if (pi.isTrue(typeTable, variables, tokens, v)) {
00146 Value temp = null;
00147 int k = 0;
00148 for (Iterator j = variables.iterator(); j.hasNext(); k++) {
00149 if (temp == null) {
00150 temp = grimp.newEqExpr((Value) j.next(), IntConstant.v(token[k]));
00151 } else {
00152 temp = new LogicalAndExpr(temp, grimp.newEqExpr((Value) j.next(), IntConstant.v(token[k])));
00153 }
00154 }
00155 if (result == null) {
00156 result = temp;
00157 } else {
00158 result = new LogicalOrExpr(result, temp);
00159 }
00160 }
00161 }
00162 setResult(result);
00163 }
00164 }