001: package dk.brics.soot.intermediate.translation;
002:
003: import java.util.ArrayList;
004: import java.util.Collection;
005: import java.util.HashMap;
006: import java.util.Iterator;
007: import java.util.LinkedList;
008: import java.util.List;
009: import java.util.Map;
010:
011: import soot.ArrayType;
012: import soot.Hierarchy;
013: import soot.RefType;
014: import soot.Scene;
015: import soot.SootClass;
016: import soot.SootMethod;
017: import soot.Type;
018: import soot.Value;
019: import soot.jimple.InstanceInvokeExpr;
020: import soot.jimple.InvokeExpr;
021: import soot.jimple.Stmt;
022: import soot.toolkits.graph.CompleteUnitGraph;
023: import dk.brics.soot.intermediate.representation.Method;
024: import dk.brics.soot.intermediate.representation.Statement;
025: import dk.brics.soot.intermediate.representation.Variable;
026:
027: @SuppressWarnings("unchecked")
028: public class JavaTranslator {
029:
030: private Hierarchy h;
031: private List<Method> methods = new LinkedList<Method>();
032: StmtTranslator st;
033: Map<String, Method> methodsignaturToMethod = new HashMap<String, Method>();
034:
035: public static final String FOOQUALIFIEDNAME = "dk.brics.soot.intermediate.foo.Foo";
036:
037: public Method[] translateApplicationClasses() {
038: h = new Hierarchy();
039: makeMethods();
040: translate();
041: return methods.toArray(new Method[0]);
042: }
043:
044: private void translate() {
045: st = new StmtTranslator(this );
046: Collection<SootClass> app = Scene.v().getApplicationClasses();
047: for (SootClass ac : app) {
048: st.setCurrentClass(ac);
049: List<SootMethod> sootMethods = ac.getMethods();
050: for (SootMethod sm : sootMethods) {
051: if (sm.isConcrete()) {
052: Method method = methodsignaturToMethod.get(sm
053: .getSignature());
054: st.setCurrentMethod(sm);
055:
056: CompleteUnitGraph cug = new CompleteUnitGraph(sm
057: .retrieveActiveBody());
058: Iterator si = cug.iterator();
059:
060: while (si.hasNext()) {
061: Stmt stmt = (Stmt) si.next();
062: st.translateStmt(stmt);
063: }
064: //System.err.println("Setting up link between entry and first stmt of the method...");
065: si = cug.getHeads().iterator();
066: while (si.hasNext()) {
067: Stmt stmt = (Stmt) si.next();
068: method.getEntry().addSucc(st.getFirst(stmt));
069: }
070: si = cug.iterator();
071: //System.err.println("Setting up link between the last statement and the first statement...");
072: while (si.hasNext()) {
073: Stmt stmt = (Stmt) si.next();
074: Iterator si2 = cug.getSuccsOf(stmt).iterator();
075: while (si2.hasNext()) {
076: Stmt stmt2 = (Stmt) si2.next();
077: st.getLast(stmt)
078: .addSucc(st.getFirst(stmt2));
079: }
080: }
081: // System.err.println("!!!!!!!!!!!!!!!!!!"+sm.getName()+"!!!!!!!!!!!!!!!!!!!!");
082: // si = cug.iterator();
083: // while (si.hasNext()) {
084: // Stmt stmt = (Stmt)si.next();
085: // System.err.println("The stmt: "+stmt+" translates to "+st.getFirst(stmt));
086: // //System.err.println(st.getFirst(stmt).getSuccs());
087: // }
088: // System.err.println("######################################");
089: }
090: }
091: }
092: }
093:
094: void makeMethods() {
095: Collection<SootClass> app = Scene.v().getApplicationClasses();
096: for (SootClass ac : app) {
097: List<SootMethod> sootMethods = ac.getMethods();
098: for (SootMethod sm : sootMethods) {
099: List<Variable> vars = new LinkedList<Variable>();
100: List<Type> params = sm.getParameterTypes();
101: for (Type pt : params) {
102: Variable v = makeVariable(pt);
103: vars.add(v);
104: }
105: Variable[] var_array = (Variable[]) vars
106: .toArray(new Variable[0]);
107: Method m = new Method(sm.getName(), var_array);
108: methods.add(m);
109: methodsignaturToMethod.put(sm.getSignature(), m);
110: }
111: }
112: }
113:
114: Variable makeVariable(Value v) {
115: return makeVariable(v.getType());
116: }
117:
118: Variable makeVariable(Type t) {
119: Variable.Type type = getType(t);
120: return new Variable(type);
121: }
122:
123: public boolean isFooType(Value v) {
124: return isFooType(v.getType());
125: }
126:
127: public boolean isFooType(Type t) {
128: return getType(t) != Variable.Type.OTHER;
129: }
130:
131: public List<SootMethod> getTargetsOf(InvokeExpr expr) {
132: if (expr instanceof InstanceInvokeExpr) {
133: return getTargetsOf(((InstanceInvokeExpr) expr).getBase(),
134: expr.getMethod());
135: }
136: List<SootMethod> targets = new ArrayList(1);
137: targets.add(expr.getMethod());
138: return targets;
139: }
140:
141: public List<SootMethod> getTargetsOf(Value v, SootMethod m) {
142: SootClass rc;
143: Type t = v.getType();
144: if (t instanceof ArrayType) {
145: rc = Scene.v().getSootClass("java.lang.Object");
146: } else {
147: rc = ((RefType) v.getType()).getSootClass();
148: }
149: List<SootMethod> targets = h.resolveAbstractDispatch(rc, m);
150: return targets;
151: }
152:
153: private Variable.Type getType(Type t) {
154: if (t instanceof RefType) {
155: if (((RefType) t).getSootClass().getName().equals(
156: FOOQUALIFIEDNAME)) {
157: return Variable.Type.FOO;
158: }
159: }
160: if (t instanceof ArrayType) {
161: return Variable.Type.OTHER;
162: }
163: return Variable.Type.OTHER;
164: }
165:
166: boolean isApplicationClass(SootClass c) {
167: Iterator aci = Scene.v().getApplicationClasses().iterator();
168: while (aci.hasNext()) {
169: SootClass ac = (SootClass) aci.next();
170: if (c.getName().equals(ac.getName())) {
171: return true;
172: }
173: }
174: return false;
175: }
176:
177: public void notSupported(String msg) {
178: System.err.println(msg);
179: System.exit(5);
180: }
181: }
|