001: /* Soot - a J*va Optimization Framework
002: * Copyright (C) 1997-1999 Raja Vallee-Rai
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the
016: * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
017: * Boston, MA 02111-1307, USA.
018: */
019:
020: package soot.jbco.bafTransformations;
021:
022: import java.util.*;
023:
024: import soot.*;
025: import soot.baf.*;
026: import soot.baf.internal.AbstractOpTypeInst;
027: import soot.jbco.IJbcoTransform;
028: import soot.jimple.DoubleConstant;
029: import soot.jimple.FloatConstant;
030: import soot.jimple.IntConstant;
031: import soot.jimple.LongConstant;
032: import soot.jimple.NullConstant;
033: import soot.toolkits.scalar.GuaranteedDefs;
034:
035: /**
036: * @author Michael Batchelder
037: *
038: * Created on 16-Jun-2006
039: */
040: public class FixUndefinedLocals extends BodyTransformer implements
041: IJbcoTransform {
042:
043: private int undefined = 0;
044:
045: public static String dependancies[] = new String[] {
046: "bb.jbco_j2bl", "bb.jbco_ful", "bb.lp" };
047:
048: public String[] getDependancies() {
049: return dependancies;
050: }
051:
052: public static String name = "bb.jbco_ful";
053:
054: public String getName() {
055: return name;
056: }
057:
058: public void outputSummary() {
059: out.println("Undefined Locals fixed with pre-initializers: "
060: + undefined);
061: }
062:
063: protected void internalTransform(Body b, String phaseName,
064: Map options) {
065: // deal with locals not defined at all used points
066:
067: int icount = 0;
068: boolean passedIDs = false;
069: HashMap bafToJLocals = soot.jbco.Main.methods2Baf2JLocals.get(b
070: .getMethod());
071: ArrayList<Value> initialized = new ArrayList<Value>();
072: PatchingChain units = b.getUnits();
073: GuaranteedDefs gd = new GuaranteedDefs(
074: new soot.toolkits.graph.ExceptionalUnitGraph(b));
075: Iterator unitIt = units.snapshotIterator();
076: Unit after = null;
077: while (unitIt.hasNext()) {
078: Unit u = (Unit) unitIt.next();
079: if (!passedIDs && u instanceof IdentityInst) {
080: Value v = ((IdentityInst) u).getLeftOp();
081: if (v instanceof Local) {
082: initialized.add(v);
083: icount++;
084: }
085: after = u;
086: continue;
087: }
088:
089: passedIDs = true;
090:
091: if (after == null) {
092: after = Baf.v().newNopInst();
093: units.addFirst(after);
094: }
095:
096: List defs = gd.getGuaranteedDefs(u);
097: Iterator useIt = u.getUseBoxes().iterator();
098: while (useIt.hasNext()) {
099: Value v = ((ValueBox) useIt.next()).getValue();
100: if (!(v instanceof Local) || defs.contains(v)
101: || initialized.contains(v))
102: continue;
103:
104: Type t = null;
105: Local l = (Local) v;
106: Local jl = (Local) bafToJLocals.get(l);
107: if (jl != null) {
108: t = jl.getType();
109: } else {
110: // We should hopefully never get here. There should be a jimple
111: // local unless it's one of our ControlDups
112: t = l.getType();
113: if (u instanceof OpTypeArgInst) {
114: OpTypeArgInst ota = (OpTypeArgInst) u;
115: t = ota.getOpType();
116: } else if (u instanceof AbstractOpTypeInst) {
117: AbstractOpTypeInst ota = (AbstractOpTypeInst) u;
118: t = ota.getOpType();
119: } else if (u instanceof IncInst)
120: t = IntType.v();
121:
122: if (t instanceof DoubleWordType
123: || t instanceof WordType) {
124: throw new RuntimeException(
125: "Shouldn't get here (t is a double or word type: in FixUndefinedLocals)");
126: }
127: }
128: Unit store = Baf.v().newStoreInst(t, l);
129: units.insertAfter(store, after);
130:
131: // TODO: is this necessary if I fix the other casting issues?
132: if (t instanceof ArrayType) {
133: Unit tmp = Baf.v().newInstanceCastInst(t);
134: units.insertBefore(tmp, store);
135: store = tmp;
136: }
137: /////
138:
139: Unit pinit = getPushInitializer(l, t);
140: units.insertBefore(pinit, store);
141: /*if (t instanceof RefType) {
142: SootClass sc = ((RefType)t).getSootClass();
143: if (sc != null)
144: units.insertAfter(Baf.v().newInstanceCastInst(t), pinit);
145: }*/
146:
147: initialized.add(l);
148: }
149: }
150:
151: if (after instanceof NopInst)
152: units.remove(after);
153: undefined += initialized.size() - icount;
154: }
155:
156: public static PushInst getPushInitializer(Local l, Type t) {
157: if (t instanceof IntegerType) {
158: return Baf.v().newPushInst(
159: IntConstant.v(soot.jbco.util.Rand.getInt()));
160: } else if (t instanceof RefLikeType
161: || t instanceof StmtAddressType) {
162: return Baf.v().newPushInst(NullConstant.v());
163: } else if (t instanceof LongType) {
164: return Baf.v().newPushInst(
165: LongConstant.v(soot.jbco.util.Rand.getLong()));
166: } else if (t instanceof FloatType) {
167: return Baf.v().newPushInst(
168: FloatConstant.v(soot.jbco.util.Rand.getFloat()));
169: } else if (t instanceof DoubleType) {
170: return Baf.v().newPushInst(
171: DoubleConstant.v(soot.jbco.util.Rand.getDouble()));
172: }
173:
174: return null;
175: }
176:
177: /*
178: *
179: private Unit findInitializerSpotFor(Value v, Unit u, UnitGraph ug,
180: GuaranteedDefs gd) {
181: List preds = ug.getPredsOf(u);
182: while (preds.size() == 1) {
183: Unit p = (Unit) preds.get(0);
184: //if (p instanceof IdentityInst)
185: // break;
186:
187: u = p;
188: preds = ug.getPredsOf(u);
189: }
190:
191: if (preds.size() <= 1)
192: return u;
193:
194: ArrayList nodef = new ArrayList();
195: Iterator pIt = preds.iterator();
196: while (pIt.hasNext()) {
197: Unit u1 = (Unit) pIt.next();
198: if (!gd.getGuaranteedDefs(u1).contains(v)) {
199: nodef.add(u1);
200: }
201: }
202:
203: if (nodef.size() == preds.size())
204: return u;
205:
206: if (nodef.size() == 1)
207: return findInitializerSpotFor(v, (Unit) nodef.get(0), ug, gd);
208:
209: throw new RuntimeException("Shouldn't Ever Get Here!");
210: }*/
211: }
|