1 package edu.berkeley.cs.megacz;
8 public class Transformer extends BodyTransformer {
10 private static Transformer instance = new Transformer();
11 private Transformer() {}
12 public static Transformer v() { return instance; }
14 public static void main(String[] args) {
15 if(args.length == 0) {
16 System.out.println("Syntax: java " + v().getClass().getName() + " [soot options]");
19 PackManager.v().getPack("jtp").add(new Transform("jtp.instrumenter", Transformer.v()));
20 // Just in case, resolve the PrintStream SootClass.
21 Scene.v().addBasicClass("java.io.PrintStream",SootClass.SIGNATURES);
26 public static Local viaLocal(Value v, Body b, Unit u) {
27 Local l = Jimple.v().newLocal("tmpRef" + (tfr++), v.getType());
29 b.getUnits().insertBefore(Jimple.v().newAssignStmt(l, v), u);
33 HashMap map = new HashMap();
34 HashSet size_added = new HashSet();
36 public boolean isGladiator(SootClass c) { return c.implementsInterface("edu.berkeley.cs.megacz.Gladiator"); }
37 public boolean isGladiatorField(SootField f)
38 { return isGladiator(f.getDeclaringClass()) && !f.getName().equals("this") && f.getName().indexOf('$')==-1; }
39 public SootField getGladiatorField(SootField f) {
40 SootClass c = f.getDeclaringClass();
41 SootClass oc = Scene.v().getSootClass(c.getName().substring(0, c.getName().lastIndexOf('$')));
42 if (map.get(f) != null) return (SootField)map.get(f);
43 SootField nf = new SootField(c.getShortName().substring(c.getShortName().lastIndexOf('$')+1) + "$" + f.getName(),
44 f.getType().makeArrayType(),
47 Body body = oc.getMethod("<init>", new LinkedList()).getActiveBody();
48 Expr newArr = Jimple.v().newNewArrayExpr(f.getType(), IntConstant.v(1000));
49 Local newArrLocal = Jimple.v().newLocal("tmpRef" + (tfr++), f.getType().makeArrayType());
50 body.getLocals().add(newArrLocal);
51 InstanceFieldRef ifr = Jimple.v().newInstanceFieldRef(body.getThisLocal(), nf.makeRef());
52 body.getUnits().addFirst(Jimple.v().newAssignStmt(ifr, newArrLocal));
53 body.getUnits().addFirst(Jimple.v().newAssignStmt(newArrLocal, newArr));
59 public SootFieldRef getGladiatorFieldSizeRef(SootClass c) {
60 SootClass mc = Scene.v().getMainClass();
61 String name = c.getShortName().substring(c.getShortName().lastIndexOf('$')+1) + "_size";
62 if (map.get(c) == null) {
63 SootField f = new SootField(name, IntType.v());
65 Body body = mc.getMethod("<init>", new LinkedList()).getActiveBody();
66 InstanceFieldRef ifr = Jimple.v().newInstanceFieldRef(body.getThisLocal(), f.makeRef());
67 body.getUnits().addFirst(Jimple.v().newAssignStmt(ifr, IntConstant.v(0)));
71 return Scene.v().makeFieldRef(mc, name, IntType.v(), false);
74 public boolean isGladiatorType(Type t) {
75 return (t instanceof RefType) && isGladiator(((RefType)t).getSootClass());
78 public SootMethodRef convert(SootMethodRef mr) {
79 List l = mr.parameterTypes();
80 List l2 = new LinkedList();
81 for(Iterator it2 = l.iterator(); it2.hasNext();) {
82 Type t = (Type)it2.next();
83 l2.add(isGladiatorType(t) ? IntType.v() : t);
85 return Scene.v().makeMethodRef(mr.declaringClass(),
88 isGladiatorType(mr.returnType()) ? IntType.v() : mr.returnType(),
93 public void internalTransform(Body bz, String phaseName, Map options) {
94 System.out.println("============= " + phaseName);
97 nuke(Scene.v().getSootClass("edu.berkeley.cs.megacz.Test$Inner"));
98 nuke(Scene.v().getSootClass("edu.berkeley.cs.megacz.Test"));
100 public void nuke(SootClass c) {
101 for(Iterator it = c.getFields().iterator(); it.hasNext();) {
102 SootField f = (SootField)it.next();
103 Type t = f.getType();
104 if (!(t instanceof RefType)) continue;
105 if (isGladiator(((RefType)t).getSootClass())) f.setType(IntType.v());
108 List list = new LinkedList(); list.addAll(c.getMethods());
109 for(Iterator it = list.iterator(); it.hasNext();) {
110 SootMethod m = (SootMethod)it.next();
111 if (m.hasActiveBody()) m.setActiveBody(fixBody(m.getActiveBody()));
112 if (m.getName().equals("<init>")) continue;
113 if (m.getName().equals("<clinit>")) continue;
114 //if (map.get(m) != null) continue;
115 //map.put(m, Boolean.TRUE);
116 System.out.println(m.getName() + " -- " + m.getActiveBody());
117 List l2 = new LinkedList();
118 List l = m.getParameterTypes();
119 for(Iterator it2 = l.iterator(); it2.hasNext();) {
120 Type t = (Type)it2.next();
122 l2.add(isGladiatorType(t) ? IntType.v() : t);
123 //if (isGladiatorType(t)) System.out.println("ought to swap " + t);
125 Type t = m.getReturnType();
127 SootMethod meth = new SootMethod(m.getName(), l2, isGladiatorType(t) ? IntType.v() : t, m.getModifiers());
128 meth.setActiveBody(m.getActiveBody());
134 protected Body fixBody(Body body) {
136 Chain units = body.getUnits();
137 Iterator stmtIt = units.snapshotIterator();
138 for(Iterator it = body.getLocals().snapshotIterator(); it.hasNext();) {
139 Local l = (Local)it.next();
140 if (isGladiatorType(l.getType())) l.setType(IntType.v());
142 while(stmtIt.hasNext()) {
143 Stmt s = (Stmt) stmtIt.next();
144 List l = s.getUseAndDefBoxes();
145 for(Iterator it = l.iterator(); it.hasNext();) {
146 Object o = it.next();
147 if (o instanceof ValueBox) {
148 ValueBox vb = (ValueBox)o;
149 Value v = vb.getValue();
151 if (v instanceof InvokeExpr) {
152 InvokeExpr ie = (InvokeExpr)v;
153 SootMethodRef mr = ie.getMethodRef();
154 if (isGladiator(mr.declaringClass())) {
155 body.getUnits().remove(s);
158 ie.setMethodRef(convert(mr));
160 } else if (v instanceof NewExpr) {
161 NewExpr ne = (NewExpr)v;
162 if (isGladiatorType(ne.getBaseType())) {
163 System.out.println("******");
164 SootClass mc = Scene.v().getMainClass();
165 SootClass sc = ((RefType)ne.getBaseType()).getSootClass();
166 System.out.println(sc);
167 InstanceFieldRef sfr = Jimple.v().newInstanceFieldRef(body.getThisLocal(),
168 getGladiatorFieldSizeRef(sc));
169 Local ll = viaLocal(sfr, body, s);
170 Local ll2 = Jimple.v().newLocal("tmpRef" + (tfr++), IntType.v());
171 body.getLocals().add(ll2);
172 Stmt stmt = Jimple.v().newAssignStmt(ll2, Jimple.v().newAddExpr(ll, IntConstant.v(1)));
173 units.insertBefore(stmt, s);
174 units.insertAfter(Jimple.v().newAssignStmt(sfr, ll2), stmt);
178 } else if (v instanceof InstanceFieldRef) {
179 InstanceFieldRef ifr = (InstanceFieldRef)v;
180 Type t = ifr.getType();
181 if ((t instanceof RefType) && isGladiator(((RefType)t).getSootClass())) {
182 SootClass tc = ((RefType)t).getSootClass();
183 SootClass mc = Scene.v().getMainClass();
184 SootFieldRef fr = Scene.v().makeFieldRef(mc, "z", IntType.v(), false);
187 SootField f = ifr.getField();
188 if (isGladiatorField(f)) {
189 f = getGladiatorField(f);
190 SootClass mc = Scene.v().getMainClass();
191 SootField sf = mc.getField(f.getName(), f.getType());
192 InstanceFieldRef sfr = Jimple.v().newInstanceFieldRef(body.getThisLocal(), sf.makeRef());
193 ArrayRef ar = Jimple.v().newArrayRef(viaLocal(sfr, body, s), ifr.getBase());