/* Soot - a J*va Optimization Framework * Copyright (C) 2003 Navindra Umanee <navindra@cs.mcgill.ca> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ package soot.shimple.toolkits.scalar; import soot.*; import soot.util.*; import soot.shimple.*; import soot.toolkits.scalar.*; import java.util.*; /** * This class implements the LocalDefs interface for Shimple. * ShimpleLocalDefs can be used in conjunction with SimpleLocalUses to * provide Definition/Use and Use/Definition chains in SSA. * * <p> This implementation can be considered a small demo for how SSA * can be put to good use since it is much simpler than * soot.toolkits.scalar.SimpleLocalDefs. Shimple can often be treated * as Jimple with the added benefits of SSA assumptions. * * <p> In addition to the interface required by LocalDefs, * ShimpleLocalDefs also provides a method for obtaining the * definition Unit given only the Local. * * @author Navindra Umanee * @see ShimpleLocalUses * @see soot.toolkits.scalar.SimpleLocalDefs * @see soot.toolkits.scalar.SimpleLocalUses **/ public class ShimpleLocalDefs implements LocalDefs { protected Map<Value, SingletonList> localToDefs; /** * Build a LocalDefs interface from a ShimpleBody. Proper SSA * form is required, otherwise correct behaviour is not * guaranteed. **/ public ShimpleLocalDefs(ShimpleBody sb) { // Instead of rebuilding the ShimpleBody without the // programmer's knowledge, throw a RuntimeException if(!sb.isSSA()) throw new RuntimeException("ShimpleBody is not in proper SSA form as required by ShimpleLocalDefs. You may need to rebuild it or use SimpleLocalDefs instead."); // build localToDefs map simply by iterating through all the // units in the body and saving the unique definition site for // each local -- no need for fancy analysis { Chain unitsChain = sb.getUnits(); Iterator unitsIt = unitsChain.iterator(); localToDefs = new HashMap<Value, SingletonList>(unitsChain.size() * 2 + 1, 0.7f); while(unitsIt.hasNext()){ Unit unit = (Unit) unitsIt.next(); Iterator defBoxesIt = unit.getDefBoxes().iterator(); while(defBoxesIt.hasNext()){ Value value = ((ValueBox)defBoxesIt.next()).getValue(); // only map locals if(!(value instanceof Local)) continue; localToDefs.put(value, new SingletonList(unit)); } } } } /** * Unconditionally returns the definition site of a local (as a * singleton list). * * <p> This method is currently not required by the LocalDefs * interface. **/ public List<Unit> getDefsOf(Local l) { List<Unit> defs = localToDefs.get(l); if(defs == null) throw new RuntimeException("Local not found in Body."); return defs; } /** * Returns the definition site for a Local at a certain point * (Unit) in a method as a singleton list. * * @param l the Local in question. * @param s a unit that specifies the method context (location) to * query for the definitions of the Local. * @return a singleton list containing the definition site. **/ public List<Unit> getDefsOfAt(Local l, Unit s) { // For consistency with SimpleLocalDefs, check that the local // is indeed used in the given Unit. This neatly sidesteps // the problem of checking whether the local is actually // defined at the given point in the program. { Iterator boxIt = s.getUseBoxes().iterator(); boolean defined = false; while(boxIt.hasNext()){ Value value = ((ValueBox) boxIt.next()).getValue(); if(value.equals(l)){ defined = true; break; } } if(!defined) throw new RuntimeException("Illegal LocalDefs query; local " + l + " is not being used at " + s); } return getDefsOf(l); } }