Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/* Soot - a J*va Optimization Framework
* Copyright (C) 2003 John Jorgensen
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library 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.toolkits.exceptions;
import soot.*;
import soot.options.Options;
import java.util.*;
/**
*
A class for representing the set of exceptions that an
* instruction may throw.
*
*
ThrowableSet does not implement the
* {@link java.util.Set} interface, so perhaps it is misnamed.
* Instead, it provides only the operations that we require for
* determining whether a given statement might throw an exception that
* would be caught by a given handler.
*
*
There is a limitation on the combinations of operations
* permitted on a ThrowableSet. The
* ThrowableSets returned by {@link
* #whichCatchableAs(RefType)} cannot be involved in subsequent
* add() or whichCatchableAs() operations.
* That is, given
*
*
* p = s.whichCatchableAs(r)
*
*
* for any ThrowableSets and
* {@link soot.RefType RefType} r, and
*
*
* t == p.getUncaught() or
* t == p.getCaught()
*
*
* then calls to
* t.add(r), t.add(a), and s.add(t),
* will throw an {@link ThrowableSet.AlreadyHasExclusionsException}, for any
* RefTyper, {@link AnySubType} a,
* and ThrowableSett.
*
*
Actually the restrictions implemented are not quite so strict
* (there are some combinations of whichCatchableAs()
* followed by add() which will not raise an exception),
* but a more accurate description would require reference to the
* internals of the current implementation. The restrictions should
* not be too onerous for ThrowableSet's anticipated
* uses: we expect ThrowableSets to grow by accumulating
* all the exception types that a given {@link Unit} may throw, then,
* shrink as the types caught by different exception handlers are
* removed to yield the sets representing exceptions which escape
* those handlers.
*
*
The ThrowableSet class is intended to be immutable
* (hence the final modifier on its declaration). It
* does not take the step of guaranteeing immutability by cloning the
* RefLikeType objects it contains, though, because we trust
* {@link Scene} to enforce the existence of only one
* RefLikeType instance with a given name.
*/
public final class ThrowableSet {
private static final boolean INSTRUMENTING = true;
/**
* Singleton class for fields and initializers common to all
* ThrowableSet objects (i.e., these would be static fields and
* initializers, in the absence of soot's {@link G} and {@link
* Singletons} classes).
*/
public static class Manager {
/**
* Map from {@link Integer}s representing set size to all
* ThrowableSets of that size.
*/
private final Map sizeToSets = new HashMap();
/**
* ThrowableSet containing no exception classes.
*/
public final ThrowableSet EMPTY;
/**
* ThrowableSet representing all possible
* Throwables.
*/
final ThrowableSet ALL_THROWABLES;
/**
* ThrowableSet containing all the asynchronous
* and virtual machine errors, which may be thrown by any
* bytecode instruction at any point in the computation.
*/
final ThrowableSet VM_ERRORS;
/**
* ThrowableSet containing all the exceptions
* that may be thrown in the course of resolving a reference
* to another class, including the process of loading, preparing,
* and verifying the referenced class.
*/
final ThrowableSet RESOLVE_CLASS_ERRORS;
/**
* ThrowableSet containing all the exceptions
* that may be thrown in the course of resolving a reference
* to a field.
*/
final ThrowableSet RESOLVE_FIELD_ERRORS;
/**
* ThrowableSet containing all the exceptions
* that may be thrown in the course of resolving a reference
* to a non-static method.
*/
final ThrowableSet RESOLVE_METHOD_ERRORS;
/**
* ThrowableSet containing all the exceptions
* which may be thrown by instructions that have the potential
* to cause a new class to be loaded and initialized (including
* UnsatisfiedLinkError, which is raised at runtime rather than
* linking type).
*/
final ThrowableSet INITIALIZATION_ERRORS;
final RefType RUNTIME_EXCEPTION;
final RefType ARITHMETIC_EXCEPTION;
final RefType ARRAY_STORE_EXCEPTION;
final RefType CLASS_CAST_EXCEPTION;
final RefType ILLEGAL_MONITOR_STATE_EXCEPTION;
final RefType INDEX_OUT_OF_BOUNDS_EXCEPTION;
final RefType ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION;
final RefType NEGATIVE_ARRAY_SIZE_EXCEPTION;
final RefType NULL_POINTER_EXCEPTION;
final RefType INSTANTIATION_ERROR;
// counts for instrumenting:
private int registeredSets = 0;
private int addsOfRefType = 0;
private int addsOfAnySubType = 0;
private int addsOfSet = 0;
private int addsInclusionFromMap = 0;
private int addsInclusionFromMemo = 0;
private int addsInclusionFromSearch = 0;
private int addsInclusionInterrupted = 0;
private int addsExclusionWithSearch = 0;
private int addsExclusionWithoutSearch = 0;
private int removesOfAnySubType = 0;
private final int removesFromMap = 0;
private final int removesFromMemo = 0;
private int removesFromSearch = 0;
private int registrationCalls = 0;
private int catchableAsQueries = 0;
private int catchableAsFromMap = 0;
private int catchableAsFromSearch = 0;
/**
* Constructs a ThrowableSet.Manager for inclusion in
* Soot's global variable manager, {@link G}.
*
* @param g guarantees that the constructor may only be called
* from {@link Singletons}.
*/
public Manager( Singletons.Global g ) {
// First ensure the Exception classes are represented in Soot.
// Runtime errors:
RUNTIME_EXCEPTION =
Scene.v().getRefType("java.lang.RuntimeException");
ARITHMETIC_EXCEPTION =
Scene.v().getRefType("java.lang.ArithmeticException");
ARRAY_STORE_EXCEPTION =
Scene.v().getRefType("java.lang.ArrayStoreException");
CLASS_CAST_EXCEPTION =
Scene.v().getRefType("java.lang.ClassCastException");
ILLEGAL_MONITOR_STATE_EXCEPTION =
Scene.v().getRefType("java.lang.IllegalMonitorStateException");
INDEX_OUT_OF_BOUNDS_EXCEPTION =
Scene.v().getRefType("java.lang.IndexOutOfBoundsException");
ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION =
Scene.v().getRefType("java.lang.ArrayIndexOutOfBoundsException");
NEGATIVE_ARRAY_SIZE_EXCEPTION =
Scene.v().getRefType("java.lang.NegativeArraySizeException");
NULL_POINTER_EXCEPTION =
Scene.v().getRefType("java.lang.NullPointerException");
INSTANTIATION_ERROR =
Scene.v().getRefType("java.lang.InstantiationError");
EMPTY = registerSetIfNew(null, null);
Set allThrowablesSet = new HashSet();
allThrowablesSet.add(AnySubType.v(Scene.v().getRefType("java.lang.Throwable")));
ALL_THROWABLES = registerSetIfNew(allThrowablesSet, null);
Set vmErrorSet = new HashSet();
vmErrorSet.add(Scene.v().getRefType("java.lang.InternalError"));
vmErrorSet.add(Scene.v().getRefType("java.lang.OutOfMemoryError"));
vmErrorSet.add(Scene.v().getRefType("java.lang.StackOverflowError"));
vmErrorSet.add(Scene.v().getRefType("java.lang.UnknownError"));
// The Java library's deprecated Thread.stop(Throwable) method
// would actually allow _any_ Throwable to be delivered
// asynchronously, not just java.lang.ThreadDeath.
vmErrorSet.add(Scene.v().getRefType("java.lang.ThreadDeath"));
VM_ERRORS = registerSetIfNew(vmErrorSet, null);
Set resolveClassErrorSet = new HashSet();
resolveClassErrorSet.add(Scene.v().getRefType("java.lang.ClassCircularityError"));
// We add AnySubType(ClassFormatError) so that we can
// avoid adding its subclass,
// UnsupportedClassVersionError, explicitly. This is a
// hack to allow Soot to analyze older class libraries
// (UnsupportedClassVersionError was added in JDK 1.2).
if(!Options.v().j2me())
resolveClassErrorSet.add(AnySubType.v(Scene.v().getRefType("java.lang.ClassFormatError")));
resolveClassErrorSet.add(Scene.v().getRefType("java.lang.IllegalAccessError"));
resolveClassErrorSet.add(Scene.v().getRefType("java.lang.IncompatibleClassChangeError"));
resolveClassErrorSet.add(Scene.v().getRefType("java.lang.LinkageError"));
resolveClassErrorSet.add(Scene.v().getRefType("java.lang.NoClassDefFoundError"));
resolveClassErrorSet.add(Scene.v().getRefType("java.lang.VerifyError"));
RESOLVE_CLASS_ERRORS = registerSetIfNew(resolveClassErrorSet, null);
Set resolveFieldErrorSet = new HashSet(resolveClassErrorSet);
resolveFieldErrorSet.add(Scene.v().getRefType("java.lang.NoSuchFieldError"));
RESOLVE_FIELD_ERRORS = registerSetIfNew(resolveFieldErrorSet, null);
Set resolveMethodErrorSet = new HashSet(resolveClassErrorSet);
resolveMethodErrorSet.add(Scene.v().getRefType("java.lang.AbstractMethodError"));
resolveMethodErrorSet.add(Scene.v().getRefType("java.lang.NoSuchMethodError"));
resolveMethodErrorSet.add(Scene.v().getRefType("java.lang.UnsatisfiedLinkError"));
RESOLVE_METHOD_ERRORS = registerSetIfNew(resolveMethodErrorSet, null);
// The static initializers of a newly loaded class might
// throw any Error (if they threw an Exception---even a
// RuntimeException---it would be replaced by an
// ExceptionInInitializerError):
//
Set initializationErrorSet = new HashSet();
initializationErrorSet.add(AnySubType.v(Scene.v().getRefType("java.lang.Error")));
INITIALIZATION_ERRORS = registerSetIfNew(initializationErrorSet, null);
}
/**
* Returns the single instance of ThrowableSet.Manager.
*
* @return Soot's ThrowableSet.Manager.
*/
public static Manager v() {
return G.v().soot_toolkits_exceptions_ThrowableSet_Manager();
}
/**
*
Returns a ThrowableSet representing the set of
* exceptions included in include minus the set
* of exceptions included in exclude. Creates a
* new ThrowableSet only if there was not already
* one whose contents correspond to include -
* exclude.
*
* @param include A set of {@link RefLikeType}
* objects representing exception types included in the result; may
* be null if there are no included types.
*
* @param exclude A set of {@link AnySubType}
* objects representing exception types excluded from the result; may
* be null if there are no excluded types.
*
* @return a ThrowableSet representing the set of
* exceptions corresponding to include -
* exclude.
*/
private ThrowableSet registerSetIfNew(Set include, Set exclude) {
if (INSTRUMENTING) {
registrationCalls++;
}
if (include == null) {
include = Collections.EMPTY_SET;
}
if (exclude == null) {
exclude = Collections.EMPTY_SET;
}
int size = include.size() + exclude.size();
Integer sizeKey = new Integer(size);
List sizeList = sizeToSets.get(sizeKey);
if (sizeList == null) {
sizeList = new LinkedList();
sizeToSets.put(sizeKey, sizeList);
}
for (ThrowableSet set : sizeList) {
if (set.exceptionsIncluded.equals(include)
&& set.exceptionsExcluded.equals(exclude)) {
return set;
}
}
if (INSTRUMENTING) {
registeredSets++;
}
ThrowableSet result = new ThrowableSet(include, exclude);
sizeList.add(result);
return result;
}
/**
* Report the counts collected by instrumentation (for now, at
* least, there is no need to provide access to the individual
* values as numbers).
*
* @return a string listing the counts.
*/
public String reportInstrumentation() {
int setCount = 0;
for (List sizeList : sizeToSets.values()) {
setCount += sizeList.size();
}
if (setCount != registeredSets) {
throw new IllegalStateException("ThrowableSet.reportInstrumentation() assertion failure: registeredSets != list count");
}
StringBuffer buf = new StringBuffer("registeredSets: ")
.append(setCount)
.append("\naddsOfRefType: ")
.append(addsOfRefType)
.append("\naddsOfAnySubType: ")
.append(addsOfAnySubType)
.append("\naddsOfSet: ")
.append(addsOfSet)
.append("\naddsInclusionFromMap: ")
.append(addsInclusionFromMap)
.append("\naddsInclusionFromMemo: ")
.append(addsInclusionFromMemo)
.append("\naddsInclusionFromSearch: ")
.append(addsInclusionFromSearch)
.append("\naddsInclusionInterrupted: ")
.append(addsInclusionInterrupted)
.append("\naddsExclusionWithoutSearch: ")
.append(addsExclusionWithoutSearch)
.append("\naddsExclusionWithSearch: ")
.append(addsExclusionWithSearch)
.append("\nremovesOfAnySubType: ")
.append(removesOfAnySubType)
.append("\nremovesFromMap: ")
.append(removesFromMap)
.append("\nremovesFromMemo: ")
.append(removesFromMemo)
.append("\nremovesFromSearch: ")
.append(removesFromSearch)
.append("\nregistrationCalls: ")
.append(registrationCalls)
.append("\ncatchableAsQueries: ")
.append(catchableAsQueries)
.append("\ncatchableAsFromMap: ")
.append(catchableAsFromMap)
.append("\ncatchableAsFromSearch: ")
.append(catchableAsFromSearch)
.append('\n');
return buf.toString();
}
/**
* A package-private method to provide unit tests with access
* to the collection of ThrowableSets.
*/
Map getSizeToSets() {
return Manager.v().sizeToSets;
}
}
public static class AlreadyHasExclusionsException extends IllegalStateException {
public AlreadyHasExclusionsException(String s) {
super(s);
}
}
/**
* Set of exception types included within the set.
*/
private final Set exceptionsIncluded;
/**
* Set of exception types which, though members of
* exceptionsIncluded, are to be excluded from the types
* represented by this ThrowableSet. To simplify
* the implementation, once a ThrowableSet has
* any excluded types, the various add() methods of
* this class must bar additions of subtypes of those
* excluded types.
*/
private final Set exceptionsExcluded;
/**
* A map from
* ({@link RefLikeType} \\union ThrowableSet)
* to ThrowableSet. If the mapping (k,v) is in
* memoizedAdds and k is a
* ThrowableSet, then v is the set that
* results from adding all elements in k to this. If
* (k,v) is in memoizedAdds and k is a
* {@link RefLikeType}, then v is the set that results from adding
* k to this.
*/
private Map