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

soot.jimple.toolkits.pointer.LocalTypeSet Maven / Gradle / Ivy

package soot.jimple.toolkits.pointer;

/*-
 * #%L
 * Soot - a J*va Optimization Framework
 * %%
 * Copyright (C) 2003 Ondrej Lhotak
 * %%
 * 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.Iterator;
import java.util.List;

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

import soot.FastHierarchy;
import soot.Local;
import soot.RefType;
import soot.Scene;
import soot.Type;

/** Represents a set of (local,type) pairs using a bit-vector. */
class LocalTypeSet extends java.util.BitSet {
  private static final Logger logger = LoggerFactory.getLogger(LocalTypeSet.class);
  protected List locals;
  protected List types;

  /**
   * Constructs a new empty set given a list of all locals and types that may ever be in the set.
   */
  public LocalTypeSet(List locals, List types) {
    super(locals.size() * types.size());
    this.locals = locals;
    this.types = types;

    // Make sure that we have a hierarchy
    Scene.v().getOrMakeFastHierarchy();
  }

  /** Returns the number of the bit corresponding to the pair (l,t). */
  protected int indexOf(Local l, RefType t) {
    if (locals.indexOf(l) == -1 || types.indexOf(t) == -1) {
      throw new RuntimeException("Invalid local or type in LocalTypeSet");
    }
    return locals.indexOf(l) * types.size() + types.indexOf(t);
  }

  /** Removes all pairs corresponding to local l from the set. */
  public void killLocal(Local l) {
    int base = types.size() * locals.indexOf(l);
    for (int i = 0; i < types.size(); i++) {
      clear(i + base);
    }
  }

  /** For each pair (from,t), adds a pair (to,t). */
  public void localCopy(Local to, Local from) {
    int baseTo = types.size() * locals.indexOf(to);
    int baseFrom = types.size() * locals.indexOf(from);
    for (int i = 0; i < types.size(); i++) {
      if (get(i + baseFrom)) {
        set(i + baseTo);
      } else {
        clear(i + baseTo);
      }
    }
  }

  /** Empties the set. */
  public void clearAllBits() {
    for (int i = 0; i < types.size() * locals.size(); i++) {
      clear(i);
    }
  }

  /** Fills the set to contain all possible (local,type) pairs. */
  public void setAllBits() {
    for (int i = 0; i < types.size() * locals.size(); i++) {
      set(i);
    }
  }

  /** Adds to the set all pairs (l,type) where type is any supertype of t. */
  public void localMustBeSubtypeOf(Local l, RefType t) {
    FastHierarchy fh = Scene.v().getFastHierarchy();
    for (Type type : types) {
      RefType supertype = (RefType) type;
      if (fh.canStoreType(t, supertype)) {
        set(indexOf(l, supertype));
      }
    }
  }

  public String toString() {
    StringBuffer sb = new StringBuffer();
    Iterator localsIt = locals.iterator();
    while (localsIt.hasNext()) {
      Local l = localsIt.next();
      Iterator typesIt = types.iterator();
      while (typesIt.hasNext()) {
        RefType t = (RefType) typesIt.next();
        int index = indexOf(l, t);
        // logger.debug("for: "+l+" and type: "+t+" at: "+index);
        if (get(index)) {
          sb.append("((" + l + "," + t + ") -> elim cast check) ");
        }
      }

    }
    return sb.toString();
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy