/**
* This file is licensed under the University of Illinois/NCSA Open Source License. See LICENSE.TXT for details.
*/
package edu.illinois.keshmesh.detector;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.jdt.core.IJavaProject;
import com.ibm.wala.classLoader.CallSiteReference;
import com.ibm.wala.dataflow.graph.AbstractMeetOperator;
import com.ibm.wala.dataflow.graph.BitVectorUnion;
import com.ibm.wala.dataflow.graph.BitVectorUnionVector;
import com.ibm.wala.dataflow.graph.ITransferFunctionProvider;
import com.ibm.wala.fixpoint.BitVectorVariable;
import com.ibm.wala.fixpoint.UnaryOperator;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.CallGraph;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.util.intset.BitVector;
import com.ibm.wala.util.intset.IntIterator;
import com.ibm.wala.util.intset.IntSet;
import edu.illinois.keshmesh.detector.util.AnalysisUtils;
/**
*
* This class is based on LCK06JTransferFunctionProvider.
*
* @author Mohsen Vakilian
* @author Stas Negara
*
*/
public class VNA00JTransferFunctionProvider implements ITransferFunctionProvider<CGNode, BitVectorVariable> {
private final IJavaProject javaProject;
private final CallGraph callGraph;
private final Map<CGNode, CGNodeInfo> cgNodeInfoMap;
private final IClassHierarchy classHierarchy;
public VNA00JTransferFunctionProvider(IJavaProject javaProject, CallGraph callGraph, Map<CGNode, CGNodeInfo> cgNodeInfoMap, IClassHierarchy classHierarchy) {
this.javaProject = javaProject;
this.callGraph = callGraph;
this.cgNodeInfoMap = cgNodeInfoMap;
this.classHierarchy = classHierarchy;
}
@Override
public AbstractMeetOperator<BitVectorVariable> getMeetOperator() {
return BitVectorUnion.instance();
}
@Override
public boolean hasEdgeTransferFunctions() {
return true;
}
/**
* This method is the same as
* LCK06JTransferFunctionProvider#getEdgeTransferFunction except that the
* conditions of the if statements are different.
*
* This method propagates some instructions from src to dst.
*/
@Override
public UnaryOperator<BitVectorVariable> getEdgeTransferFunction(CGNode src, CGNode dst) {
if (!dst.getMethod().isSynchronized()) {
CGNodeInfo srcNodeInfo = cgNodeInfoMap.get(src);
CGNodeInfo dstNodeInfo = cgNodeInfoMap.get(dst);
Iterator<CallSiteReference> callSitesIterator = callGraph.getPossibleSites(dst, src);
IR dstIR = dst.getIR();
while (callSitesIterator.hasNext()) {
CallSiteReference callSiteReference = callSitesIterator.next();
IntSet callInstructionIndices = dstIR.getCallInstructionIndices(callSiteReference);
IntIterator instructionIndicesIterator = callInstructionIndices.intIterator();
while (instructionIndicesIterator.hasNext()) {
int invokeInstructionIndex = instructionIndicesIterator.next();
InstructionInfo instructionInfo = new InstructionInfo(javaProject, dst, invokeInstructionIndex);
if (!AnalysisUtils.isProtectedByAnySynchronizedBlock(dstNodeInfo.getSafeSynchronizedBlocks(), instructionInfo)
&& AnalysisUtils.doesAllowPropagation(instructionInfo, classHierarchy)) {
return new BitVectorUnionVector(srcNodeInfo.getBitVector());
}
}
}
}
return new BitVectorUnionVector(new BitVector());
}
@Override
public boolean hasNodeTransferFunctions() {
return false;
}
@Override
public UnaryOperator<BitVectorVariable> getNodeTransferFunction(CGNode node) {
return null;
}
}