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

soot.TrapManager Maven / Gradle / Ivy

package soot;

/*-
 * #%L
 * Soot - a J*va Optimization Framework
 * %%
 * Copyright (C) 1999 Patrick Lam
 * %%
 * 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.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import soot.util.Chain;

/** Utility methods for dealing with traps. */
public class TrapManager {
  /**
   * If exception e is caught at unit u in body b, return true; otherwise, return false.
   */
  public static boolean isExceptionCaughtAt(SootClass e, Unit u, Body b) {
    /*
     * Look through the traps t of b, checking to see if: - caught exception is e; - and, unit lies between t.beginUnit and
     * t.endUnit
     */

    Hierarchy h = Scene.v().getActiveHierarchy();
    Chain units = b.getUnits();

    for (Trap t : b.getTraps()) {
      /* Ah ha, we might win. */
      if (h.isClassSubclassOfIncluding(e, t.getException())) {
        Iterator it = units.iterator(t.getBeginUnit(), units.getPredOf(t.getEndUnit()));
        while (it.hasNext()) {
          if (u.equals(it.next())) {
            return true;
          }
        }
      }
    }

    return false;
  }

  /** Returns the list of traps caught at Unit u in Body b. */
  public static List getTrapsAt(Unit unit, Body b) {
    List trapsList = new ArrayList();
    Chain units = b.getUnits();

    for (Trap t : b.getTraps()) {
      Iterator it = units.iterator(t.getBeginUnit(), units.getPredOf(t.getEndUnit()));
      while (it.hasNext()) {
        if (unit.equals(it.next())) {
          trapsList.add(t);
        }
      }
    }

    return trapsList;
  }

  /** Returns a set of units which lie inside the range of any trap. */
  public static Set getTrappedUnitsOf(Body b) {
    Set trapsSet = new HashSet();
    Chain units = b.getUnits();

    for (Trap t : b.getTraps()) {
      Iterator it = units.iterator(t.getBeginUnit(), units.getPredOf(t.getEndUnit()));
      while (it.hasNext()) {
        trapsSet.add(it.next());
      }
    }
    return trapsSet;
  }

  /**
   * Splits all traps so that they do not cross the range rangeStart - rangeEnd. Note that rangeStart is inclusive, rangeEnd
   * is exclusive.
   */
  public static void splitTrapsAgainst(Body b, Unit rangeStart, Unit rangeEnd) {
    Chain traps = b.getTraps();
    Chain units = b.getUnits();
    Iterator trapsIt = traps.snapshotIterator();

    while (trapsIt.hasNext()) {
      Trap t = trapsIt.next();

      Iterator unitIt = units.iterator(t.getBeginUnit(), t.getEndUnit());

      boolean insideRange = false;

      while (unitIt.hasNext()) {
        Unit u = unitIt.next();
        if (u.equals(rangeStart)) {
          insideRange = true;
        }
        if (!unitIt.hasNext()) // i.e. u.equals(t.getEndUnit())
        {
          if (insideRange) {
            Trap newTrap = (Trap) t.clone();
            t.setBeginUnit(rangeStart);
            newTrap.setEndUnit(rangeStart);
            traps.insertAfter(newTrap, t);
          } else {
            break;
          }
        }
        if (u.equals(rangeEnd)) {
          // insideRange had better be true now.
          if (!insideRange) {
            throw new RuntimeException("inversed range?");
          }
          Trap firstTrap = (Trap) t.clone();
          Trap secondTrap = (Trap) t.clone();
          firstTrap.setEndUnit(rangeStart);
          secondTrap.setBeginUnit(rangeStart);
          secondTrap.setEndUnit(rangeEnd);
          t.setBeginUnit(rangeEnd);

          traps.insertAfter(firstTrap, t);
          traps.insertAfter(secondTrap, t);
        }
      }
    }
  }

  /**
   * Given a body and a unit handling an exception, returns the list of exception types possibly caught by the handler.
   */
  public static List getExceptionTypesOf(Unit u, Body body) {
    List possibleTypes = new ArrayList();

    for (Trap trap : body.getTraps()) {
      if (trap.getHandlerUnit() == u) {
        possibleTypes.add(RefType.v(trap.getException().getName()));
      }
    }

    return possibleTypes;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy