All Downloads are FREE. Search and download functionalities are using the official Maven repository.

soot.shimple.toolkits.scalar.ShimpleLocalUses Maven / Gradle / Ivy

package soot.shimple.toolkits.scalar;

/*-
 * #%L
 * Soot - a J*va Optimization Framework
 * %%
 * Copyright (C) 2003 Navindra Umanee 
 * %%
 * This program 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 program 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 General Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * .
 * #L%
 */

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import soot.Local;
import soot.Unit;
import soot.Value;
import soot.ValueBox;
import soot.shimple.ShimpleBody;
import soot.toolkits.scalar.LocalUses;
import soot.toolkits.scalar.UnitValueBoxPair;

/**
 * This class implements the LocalUses interface for Shimple. ShimpleLocalUses can be used in conjunction with
 * SimpleLocalDefs to provide Definition/Use and Use/Definition chains in SSA.
 *
 * 

* In addition to the interface required by LocalUses, ShimpleLocalUses also provides a method for obtaining the list of uses * given only the Local. Furthermore, unlike SimpleLocalUses, a LocalDefs object is not required when constructing * ShimpleLocalUses. * * @author Navindra Umanee * @see ShimpleLocalDefs * @see soot.toolkits.scalar.SimpleLocalDefs * @see soot.toolkits.scalar.SimpleLocalUses **/ public class ShimpleLocalUses implements LocalUses { private static final Logger logger = LoggerFactory.getLogger(ShimpleLocalUses.class); protected Map localToUses; /** * Build a LocalUses interface from a ShimpleBody. Proper SSA form is required, otherwise correct behaviour is not * guaranteed. **/ public ShimpleLocalUses(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 ShimpleLocalUses." + "You may need to rebuild it or use SimpleLocalUses instead."); } // initialise the map localToUses = new HashMap(); Iterator localsIt = sb.getLocals().iterator(); while (localsIt.hasNext()) { Local local = (Local) localsIt.next(); localToUses.put(local, new ArrayList()); } // iterate through the units and save each Local use in the // appropriate list -- due to SSA form, each Local has a // unique def, and therefore one appropriate list. Iterator unitsIt = sb.getUnits().iterator(); while (unitsIt.hasNext()) { Unit unit = (Unit) unitsIt.next(); Iterator boxIt = unit.getUseBoxes().iterator(); while (boxIt.hasNext()) { ValueBox box = (ValueBox) boxIt.next(); Value value = box.getValue(); if (!(value instanceof Local)) { continue; } List useList = localToUses.get(value); useList.add(new UnitValueBoxPair(unit, box)); } } } /** * Returns all the uses of the given Local as a list of UnitValueBoxPairs, each containing a Unit that uses the local and * the corresponding ValueBox containing the Local. * *

* This method is currently not required by the LocalUses interface. **/ public List getUsesOf(Local local) { List uses = localToUses.get(local); if (uses == null) { return Collections.EMPTY_LIST; } return uses; } /** * If a Local is defined in the Unit, returns all the uses of that Local as a list of UnitValueBoxPairs, each containing a * Unit that uses the local and the corresponding ValueBox containing the Local. **/ public List getUsesOf(Unit unit) { List defBoxes = unit.getDefBoxes(); switch (defBoxes.size()) { case 0: return Collections.EMPTY_LIST; case 1: Value local = ((ValueBox) defBoxes.get(0)).getValue(); if (!(local instanceof Local)) { return Collections.EMPTY_LIST; } return getUsesOf((Local) local); default: logger.warn("Unit has multiple definition boxes?"); List usesList = new ArrayList(); Iterator defBoxesIt = defBoxes.iterator(); while (defBoxesIt.hasNext()) { Value def = ((ValueBox) defBoxesIt.next()).getValue(); if (def instanceof Local) { usesList.addAll(getUsesOf((Local) def)); } } return usesList; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy