JavaScript slicer support
This commit is contained in:
parent
02fdb60519
commit
3910608d60
|
@ -12,6 +12,7 @@ package com.ibm.wala.cast.java.ipa.modref;
|
|||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.ibm.wala.cast.ipa.callgraph.AstHeapModel;
|
||||
import com.ibm.wala.cast.ipa.modref.AstModRef;
|
||||
import com.ibm.wala.cast.java.ssa.AstJavaInstructionVisitor;
|
||||
import com.ibm.wala.cast.java.ssa.AstJavaInvokeInstruction;
|
||||
|
@ -29,7 +30,7 @@ public class AstJavaModRef extends AstModRef {
|
|||
{
|
||||
|
||||
protected AstJavaRefVisitor(CGNode n, Collection<PointerKey> result, PointerAnalysis pa, ExtendedHeapModel h) {
|
||||
super(n, result, pa, h);
|
||||
super(n, result, pa, (AstHeapModel)h);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -55,7 +56,7 @@ public class AstJavaModRef extends AstModRef {
|
|||
{
|
||||
|
||||
protected AstJavaModVisitor(CGNode n, Collection<PointerKey> result, ExtendedHeapModel h, PointerAnalysis pa) {
|
||||
super(n, result, h, pa);
|
||||
super(n, result, (AstHeapModel)h, pa);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package com.ibm.wala.cast.js.test;
|
||||
|
||||
import org.junit.Before;
|
||||
|
||||
import com.ibm.wala.cast.js.translator.CAstRhinoTranslatorFactory;
|
||||
|
||||
public class TestJavaScriptSlicerRhino extends TestJavaScriptSlicer {
|
||||
|
||||
public static void main(String[] args) {
|
||||
justThisTest(TestJavaScriptSlicerRhino.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Before
|
||||
public void setUp() {
|
||||
com.ibm.wala.cast.js.ipa.callgraph.JSCallGraphUtil.setTranslatorFactory(new CAstRhinoTranslatorFactory());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
function _slice_target_fn(x) {
|
||||
|
||||
}
|
||||
|
||||
var x = 7;
|
||||
|
||||
var o = { f: 7 };
|
||||
|
||||
if (o != null) {
|
||||
o = (function _push_o(x) { return x>0? x: -1; })(o.f);
|
||||
|
||||
var p = { };
|
||||
|
||||
_slice_target_fn(o);
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.ibm.wala.cast.js.test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.ibm.wala.cast.js.ipa.callgraph.JSCFABuilder;
|
||||
import com.ibm.wala.cast.js.ipa.modref.JavaScriptModRef;
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.core.tests.slicer.SlicerTest;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.slicer.NormalStatement;
|
||||
import com.ibm.wala.ipa.slicer.SDG;
|
||||
import com.ibm.wala.ipa.slicer.Slicer;
|
||||
import com.ibm.wala.ipa.slicer.Slicer.ControlDependenceOptions;
|
||||
import com.ibm.wala.ipa.slicer.Slicer.DataDependenceOptions;
|
||||
import com.ibm.wala.ipa.slicer.Statement;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.WalaException;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.intset.IntSetAction;
|
||||
|
||||
public class TestJavaScriptSlicer extends TestJSCallGraphShape {
|
||||
|
||||
@Test
|
||||
public void testSimpleData() throws IOException, WalaException, IllegalArgumentException, CancelException {
|
||||
Collection<Statement> result = slice("slice1.js", DataDependenceOptions.FULL, ControlDependenceOptions.NONE);
|
||||
|
||||
for(Statement r : result) {
|
||||
System.err.println(r);
|
||||
}
|
||||
|
||||
Assert.assertEquals(0, SlicerTest.countConditionals(result));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleAll() throws IOException, WalaException, IllegalArgumentException, CancelException {
|
||||
Collection<Statement> result = slice("slice1.js", DataDependenceOptions.FULL, ControlDependenceOptions.FULL);
|
||||
|
||||
for(Statement r : result) {
|
||||
System.err.println(r);
|
||||
}
|
||||
|
||||
Assert.assertEquals(2, SlicerTest.countConditionals(result));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleControl() throws IOException, WalaException, IllegalArgumentException, CancelException {
|
||||
Collection<Statement> result = slice("slice1.js", DataDependenceOptions.NONE, ControlDependenceOptions.FULL);
|
||||
|
||||
for(Statement r : result) {
|
||||
System.err.println(r);
|
||||
}
|
||||
|
||||
Assert.assertEquals(1, SlicerTest.countConditionals(result));
|
||||
}
|
||||
|
||||
private Collection<Statement> slice(String file, DataDependenceOptions data, ControlDependenceOptions ctrl) throws IOException, WalaException, CancelException {
|
||||
JSCFABuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", file);
|
||||
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||
|
||||
final Collection<Statement> ss = findTargetStatement(CG);
|
||||
|
||||
SDG sdg = new SDG(CG, B.getPointerAnalysis(), new JavaScriptModRef(), data, ctrl);
|
||||
Collection<Statement> result = Slicer.computeBackwardSlice(sdg, ss);
|
||||
return result;
|
||||
}
|
||||
|
||||
private Collection<Statement> findTargetStatement(CallGraph CG) {
|
||||
final Collection<Statement> ss = HashSetFactory.make();
|
||||
for(CGNode n : getNodes(CG, "suffix:_slice_target_fn")) {
|
||||
for(Iterator<CGNode> callers = CG.getPredNodes(n); callers.hasNext(); ) {
|
||||
final CGNode caller = callers.next();
|
||||
for(Iterator<CallSiteReference> sites = CG.getPossibleSites(caller, n); sites.hasNext(); ) {
|
||||
caller.getIR().getCallInstructionIndices(sites.next()).foreach(new IntSetAction() {
|
||||
@Override
|
||||
public void act(int x) {
|
||||
ss.add(new NormalStatement(caller, x));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return ss;
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@ Export-Package: .,
|
|||
com.ibm.wala.cast.js.ipa.callgraph,
|
||||
com.ibm.wala.cast.js.ipa.callgraph.correlations,
|
||||
com.ibm.wala.cast.js.ipa.callgraph.correlations.extraction,
|
||||
com.ibm.wala.cast.js.ipa.modref,
|
||||
com.ibm.wala.cast.js.ipa.summaries,
|
||||
com.ibm.wala.cast.js.loader,
|
||||
com.ibm.wala.cast.js.ssa,
|
||||
|
|
|
@ -219,6 +219,9 @@ public class PropertyNameContextSelector implements ContextSelector {
|
|||
// use a MarkerForInContext to clone based on the InstanceKey used in the caller context
|
||||
// TODO the cast below isn't safe; fix
|
||||
InstanceKey callerIk = ((PropNameContext)caller.getContext()).getInstanceKey();
|
||||
if (caller.toString().contains("_mixin_for_each_fn")) {
|
||||
System.err.println(callerIk + "@" + site);
|
||||
}
|
||||
return new MarkerForInContext(baseContext, callerIk);
|
||||
} else {
|
||||
return baseContext;
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
package com.ibm.wala.cast.js.ipa.modref;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.ibm.wala.cast.ipa.callgraph.AstHeapModel;
|
||||
import com.ibm.wala.cast.ipa.modref.AstModRef;
|
||||
import com.ibm.wala.cast.js.ssa.JSInstructionVisitor;
|
||||
import com.ibm.wala.cast.js.ssa.JavaScriptCheckReference;
|
||||
import com.ibm.wala.cast.js.ssa.JavaScriptInstanceOf;
|
||||
import com.ibm.wala.cast.js.ssa.JavaScriptInvoke;
|
||||
import com.ibm.wala.cast.js.ssa.JavaScriptPropertyRead;
|
||||
import com.ibm.wala.cast.js.ssa.JavaScriptPropertyWrite;
|
||||
import com.ibm.wala.cast.js.ssa.JavaScriptTypeOfInstruction;
|
||||
import com.ibm.wala.cast.js.ssa.JavaScriptWithRegion;
|
||||
import com.ibm.wala.cast.js.ssa.PrototypeLookup;
|
||||
import com.ibm.wala.cast.js.ssa.SetPrototype;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
import com.ibm.wala.ipa.modref.ExtendedHeapModel;
|
||||
|
||||
public class JavaScriptModRef extends AstModRef {
|
||||
|
||||
protected static class JavaScriptRefVisitor extends AstRefVisitor implements JSInstructionVisitor {
|
||||
|
||||
protected JavaScriptRefVisitor(CGNode n, Collection<PointerKey> result, PointerAnalysis pa, ExtendedHeapModel h) {
|
||||
super(n, result, pa, (AstHeapModel)h);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitJavaScriptInvoke(JavaScriptInvoke instruction) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTypeOf(JavaScriptTypeOfInstruction instruction) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitJavaScriptPropertyRead(JavaScriptPropertyRead instruction) {
|
||||
PointerKey obj = h.getPointerKeyForLocal(n, instruction.getObjectRef());
|
||||
PointerKey prop = h.getPointerKeyForLocal(n, instruction.getMemberRef());
|
||||
for(InstanceKey o : pa.getPointsToSet(obj)) {
|
||||
for(InstanceKey p : pa.getPointsToSet(prop)) {
|
||||
for(Iterator<PointerKey> keys = h.getPointerKeysForReflectedFieldRead(o, p); keys.hasNext(); ) {
|
||||
PointerKey x = keys.next();
|
||||
assert x != null : instruction;
|
||||
result.add(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitJavaScriptPropertyWrite(JavaScriptPropertyWrite instruction) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitJavaScriptInstanceOf(JavaScriptInstanceOf instruction) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitWithRegion(JavaScriptWithRegion instruction) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitCheckRef(JavaScriptCheckReference instruction) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitSetPrototype(SetPrototype instruction) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPrototypeLookup(PrototypeLookup instruction) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RefVisitor makeRefVisitor(CGNode n, Collection<PointerKey> result, PointerAnalysis pa, ExtendedHeapModel h) {
|
||||
return new JavaScriptRefVisitor(n, result, pa, h);
|
||||
}
|
||||
|
||||
protected static class JavaScriptModVisitor extends AstModVisitor implements JSInstructionVisitor {
|
||||
|
||||
protected JavaScriptModVisitor(CGNode n, Collection<PointerKey> result, ExtendedHeapModel h, PointerAnalysis pa) {
|
||||
super(n, result, (AstHeapModel)h, pa);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitJavaScriptInvoke(JavaScriptInvoke instruction) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTypeOf(JavaScriptTypeOfInstruction instruction) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitJavaScriptPropertyRead(JavaScriptPropertyRead instruction) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitJavaScriptPropertyWrite(JavaScriptPropertyWrite instruction) {
|
||||
PointerKey obj = h.getPointerKeyForLocal(n, instruction.getObjectRef());
|
||||
PointerKey prop = h.getPointerKeyForLocal(n, instruction.getMemberRef());
|
||||
for(InstanceKey o : pa.getPointsToSet(obj)) {
|
||||
for(InstanceKey p : pa.getPointsToSet(prop)) {
|
||||
for(Iterator<PointerKey> keys = h.getPointerKeysForReflectedFieldWrite(o, p); keys.hasNext(); ) {
|
||||
PointerKey x = keys.next();
|
||||
assert x != null : instruction;
|
||||
result.add(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitJavaScriptInstanceOf(JavaScriptInstanceOf instruction) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitWithRegion(JavaScriptWithRegion instruction) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitCheckRef(JavaScriptCheckReference instruction) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitSetPrototype(SetPrototype instruction) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPrototypeLookup(PrototypeLookup instruction) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ModVisitor makeModVisitor(CGNode n, Collection<PointerKey> result, PointerAnalysis pa, ExtendedHeapModel h, boolean ignoreAllocHeapDefs) {
|
||||
return new JavaScriptModVisitor(n, result, h, pa);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package com.ibm.wala.cast.ipa.callgraph;
|
||||
|
||||
import com.ibm.wala.ipa.modref.ExtendedHeapModel;
|
||||
|
||||
public interface AstHeapModel extends ExtendedHeapModel, AstPointerKeyFactory {
|
||||
|
||||
}
|
|
@ -44,20 +44,24 @@ import com.ibm.wala.ipa.callgraph.CGNode;
|
|||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.impl.ExplicitCallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.AbstractFieldPointerKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.HeapModel;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKeyFactory;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.LocalPointerKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysisImpl;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKeyFactory;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointsToMap;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointsToSetVariable;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PropagationCallGraphBuilder;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PropagationSystem;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.cfa.DefaultSSAInterpreter;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.cfa.DelegatingSSAContextInterpreter;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.ipa.modref.ArrayLengthKey;
|
||||
import com.ibm.wala.ssa.DefUse;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.SSAPutInstruction;
|
||||
|
@ -107,6 +111,7 @@ public abstract class AstSSAPropagationCallGraphBuilder extends SSAPropagationCa
|
|||
//
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
protected AstSSAPropagationCallGraphBuilder(IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache,
|
||||
PointerKeyFactory pointerKeyFactory) {
|
||||
super(cha, options, cache, pointerKeyFactory);
|
||||
|
@ -132,6 +137,16 @@ public abstract class AstSSAPropagationCallGraphBuilder extends SSAPropagationCa
|
|||
//
|
||||
// /////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
protected PropagationSystem makeSystem(AnalysisOptions options) {
|
||||
return new PropagationSystem(callGraph, pointerKeyFactory, instanceKeyFactory) {
|
||||
@Override
|
||||
public PointerAnalysis makePointerAnalysis(PropagationCallGraphBuilder builder) {
|
||||
return new AstPointerAnalysisImpl(builder, cg, pointsToMap, instanceKeys, pointerKeyFactory, instanceKeyFactory);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static class AstPointerAnalysisImpl extends PointerAnalysisImpl {
|
||||
|
||||
public AstPointerAnalysisImpl(PropagationCallGraphBuilder builder, CallGraph cg, PointsToMap pointsToMap,
|
||||
|
@ -139,6 +154,34 @@ public abstract class AstSSAPropagationCallGraphBuilder extends SSAPropagationCa
|
|||
super(builder, cg, pointsToMap, instanceKeys, pointerKeys, iKeyFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HeapModel makeHeapModel() {
|
||||
class Model extends HModel implements AstHeapModel {
|
||||
@Override
|
||||
public PointerKey getPointerKeyForArrayLength(InstanceKey I) {
|
||||
return new ArrayLengthKey(I);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<PointerKey> getPointerKeysForReflectedFieldRead(InstanceKey I, InstanceKey F) {
|
||||
return ((AstPointerKeyFactory)pointerKeys).getPointerKeysForReflectedFieldRead(I, F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<PointerKey> getPointerKeysForReflectedFieldWrite(InstanceKey I, InstanceKey F) {
|
||||
return ((AstPointerKeyFactory)pointerKeys).getPointerKeysForReflectedFieldWrite(I, F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PointerKey getPointerKeyForObjectCatalog(InstanceKey I) {
|
||||
return ((AstPointerKeyFactory)pointerKeys).getPointerKeyForObjectCatalog(I);
|
||||
}
|
||||
}
|
||||
|
||||
return new Model();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected ImplicitPointsToSetVisitor makeImplicitPointsToVisitor(LocalPointerKey lpk) {
|
||||
return new AstImplicitPointsToSetVisitor(this, lpk);
|
||||
|
|
|
@ -12,6 +12,7 @@ package com.ibm.wala.cast.ipa.modref;
|
|||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.ibm.wala.cast.ipa.callgraph.AstHeapModel;
|
||||
import com.ibm.wala.cast.ir.ssa.AstAssertInstruction;
|
||||
import com.ibm.wala.cast.ir.ssa.AstEchoInstruction;
|
||||
import com.ibm.wala.cast.ir.ssa.AstGlobalRead;
|
||||
|
@ -30,12 +31,14 @@ import com.ibm.wala.ipa.modref.ModRef;
|
|||
|
||||
public class AstModRef extends ModRef {
|
||||
|
||||
protected static class AstRefVisitor
|
||||
extends RefVisitor
|
||||
implements AstInstructionVisitor
|
||||
{
|
||||
@Override
|
||||
public ExtendedHeapModel makeHeapModel(PointerAnalysis pa) {
|
||||
return (AstHeapModel)pa.getHeapModel();
|
||||
}
|
||||
|
||||
protected static class AstRefVisitor extends RefVisitor<AstHeapModel> implements AstInstructionVisitor {
|
||||
|
||||
protected AstRefVisitor(CGNode n, Collection<PointerKey> result, PointerAnalysis pa, ExtendedHeapModel h) {
|
||||
protected AstRefVisitor(CGNode n, Collection<PointerKey> result, PointerAnalysis pa, AstHeapModel h) {
|
||||
super(n, result, pa, h);
|
||||
}
|
||||
|
||||
|
@ -87,15 +90,15 @@ public class AstModRef extends ModRef {
|
|||
|
||||
@Override
|
||||
protected RefVisitor makeRefVisitor(CGNode n, Collection<PointerKey> result, PointerAnalysis pa, ExtendedHeapModel h) {
|
||||
return new AstRefVisitor(n, result, pa, h);
|
||||
return new AstRefVisitor(n, result, pa, (AstHeapModel)h);
|
||||
}
|
||||
|
||||
protected static class AstModVisitor
|
||||
extends ModVisitor
|
||||
extends ModVisitor <AstHeapModel>
|
||||
implements AstInstructionVisitor
|
||||
{
|
||||
|
||||
protected AstModVisitor(CGNode n, Collection<PointerKey> result, ExtendedHeapModel h, PointerAnalysis pa) {
|
||||
protected AstModVisitor(CGNode n, Collection<PointerKey> result, AstHeapModel h, PointerAnalysis pa) {
|
||||
super(n, result, h, pa, true);
|
||||
}
|
||||
|
||||
|
@ -147,7 +150,7 @@ public class AstModRef extends ModRef {
|
|||
|
||||
@Override
|
||||
protected ModVisitor makeModVisitor(CGNode n, Collection<PointerKey> result, PointerAnalysis pa, ExtendedHeapModel h, boolean ignoreAllocHeapDefs) {
|
||||
return new AstModVisitor(n, result, h, pa);
|
||||
return new AstModVisitor(n, result, (AstHeapModel)h, pa);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ public class PointerAnalysisImpl extends AbstractPointerAnalysis {
|
|||
/**
|
||||
* An object that abstracts how to model pointers in the heap.
|
||||
*/
|
||||
private final PointerKeyFactory pointerKeys;
|
||||
protected final PointerKeyFactory pointerKeys;
|
||||
|
||||
/**
|
||||
* An object that abstracts how to model instances in the heap.
|
||||
|
@ -100,7 +100,7 @@ public class PointerAnalysisImpl extends AbstractPointerAnalysis {
|
|||
return result.toString();
|
||||
}
|
||||
|
||||
private HeapModel makeHeapModel() {
|
||||
protected HeapModel makeHeapModel() {
|
||||
return new HModel();
|
||||
}
|
||||
|
||||
|
@ -454,7 +454,7 @@ public class PointerAnalysisImpl extends AbstractPointerAnalysis {
|
|||
return H;
|
||||
}
|
||||
|
||||
private class HModel implements HeapModel {
|
||||
protected class HModel implements HeapModel {
|
||||
|
||||
@Override
|
||||
public Iterator<PointerKey> iteratePointerKeys() {
|
||||
|
|
|
@ -128,6 +128,9 @@ public class ModRef {
|
|||
});
|
||||
}
|
||||
|
||||
public ExtendedHeapModel makeHeapModel(PointerAnalysis pa) {
|
||||
return new DelegatingExtendedHeapModel(pa.getHeapModel());
|
||||
}
|
||||
/**
|
||||
* For a call graph node, what heap locations (as determined by a heap model) may it write, <bf> NOT </bf> including it's callees
|
||||
* transitively
|
||||
|
@ -136,12 +139,13 @@ public class ModRef {
|
|||
*/
|
||||
private Collection<PointerKey> scanNodeForMod(final CGNode n, final PointerAnalysis pa, HeapExclusions heapExclude) {
|
||||
Collection<PointerKey> result = HashSetFactory.make();
|
||||
final ExtendedHeapModel h = new DelegatingExtendedHeapModel(pa.getHeapModel());
|
||||
final ExtendedHeapModel h = makeHeapModel(pa);
|
||||
SSAInstruction.Visitor v = makeModVisitor(n, result, pa, h);
|
||||
IR ir = n.getIR();
|
||||
if (ir != null) {
|
||||
for (Iterator<SSAInstruction> it = ir.iterateNormalInstructions(); it.hasNext();) {
|
||||
it.next().visit(v);
|
||||
assert ! result.contains(null);
|
||||
}
|
||||
}
|
||||
if (heapExclude != null) {
|
||||
|
@ -156,13 +160,15 @@ public class ModRef {
|
|||
*/
|
||||
private Collection<PointerKey> scanNodeForRef(final CGNode n, final PointerAnalysis pa, HeapExclusions heapExclude) {
|
||||
Collection<PointerKey> result = HashSetFactory.make();
|
||||
final ExtendedHeapModel h = new DelegatingExtendedHeapModel(pa.getHeapModel());
|
||||
final ExtendedHeapModel h = makeHeapModel(pa);
|
||||
SSAInstruction.Visitor v = makeRefVisitor(n, result, pa, h);
|
||||
IR ir = n.getIR();
|
||||
if (ir != null) {
|
||||
for (Iterator<SSAInstruction> it = ir.iterateNormalInstructions(); it.hasNext();) {
|
||||
it.next().visit(v);
|
||||
}
|
||||
SSAInstruction x = it.next();
|
||||
x.visit(v);
|
||||
assert ! result.contains(null) : x;
|
||||
}
|
||||
}
|
||||
if (heapExclude != null) {
|
||||
result = heapExclude.filter(result);
|
||||
|
@ -170,16 +176,16 @@ public class ModRef {
|
|||
return result;
|
||||
}
|
||||
|
||||
protected static class RefVisitor extends SSAInstruction.Visitor {
|
||||
private final CGNode n;
|
||||
protected static class RefVisitor<H extends ExtendedHeapModel> extends SSAInstruction.Visitor {
|
||||
protected final CGNode n;
|
||||
|
||||
private final Collection<PointerKey> result;
|
||||
protected final Collection<PointerKey> result;
|
||||
|
||||
private final PointerAnalysis pa;
|
||||
protected final PointerAnalysis pa;
|
||||
|
||||
private final ExtendedHeapModel h;
|
||||
protected final H h;
|
||||
|
||||
protected RefVisitor(CGNode n, Collection<PointerKey> result, PointerAnalysis pa, ExtendedHeapModel h) {
|
||||
protected RefVisitor(CGNode n, Collection<PointerKey> result, PointerAnalysis pa, H h) {
|
||||
this.n = n;
|
||||
this.result = result;
|
||||
this.pa = pa;
|
||||
|
@ -211,25 +217,28 @@ public class ModRef {
|
|||
} else {
|
||||
PointerKey ref = h.getPointerKeyForLocal(n, instruction.getRef());
|
||||
for (InstanceKey i : pa.getPointsToSet(ref)) {
|
||||
result.add(h.getPointerKeyForInstanceField(i, f));
|
||||
PointerKey x = h.getPointerKeyForInstanceField(i, f);
|
||||
if (x != null) {
|
||||
result.add(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static class ModVisitor extends SSAInstruction.Visitor {
|
||||
private final CGNode n;
|
||||
protected static class ModVisitor<H extends ExtendedHeapModel> extends SSAInstruction.Visitor {
|
||||
protected final CGNode n;
|
||||
|
||||
private final Collection<PointerKey> result;
|
||||
protected final Collection<PointerKey> result;
|
||||
|
||||
private final ExtendedHeapModel h;
|
||||
protected final H h;
|
||||
|
||||
private final PointerAnalysis pa;
|
||||
protected final PointerAnalysis pa;
|
||||
|
||||
private final boolean ignoreAllocHeapDefs;
|
||||
|
||||
protected ModVisitor(CGNode n, Collection<PointerKey> result, ExtendedHeapModel h, PointerAnalysis pa,
|
||||
protected ModVisitor(CGNode n, Collection<PointerKey> result, H h, PointerAnalysis pa,
|
||||
boolean ignoreAllocHeapDefs) {
|
||||
this.n = n;
|
||||
this.result = result;
|
||||
|
@ -360,7 +369,7 @@ public class ModRef {
|
|||
}
|
||||
|
||||
protected RefVisitor makeRefVisitor(CGNode n, Collection<PointerKey> result, PointerAnalysis pa, ExtendedHeapModel h) {
|
||||
return new RefVisitor(n, result, pa, h);
|
||||
return new RefVisitor<ExtendedHeapModel>(n, result, pa, h);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -73,8 +73,11 @@ public class HeapReachingDefs {
|
|||
|
||||
private final ModRef modRef;
|
||||
|
||||
public HeapReachingDefs(ModRef modRef) {
|
||||
private final ExtendedHeapModel heapModel;
|
||||
|
||||
public HeapReachingDefs(ModRef modRef, ExtendedHeapModel heapModel) {
|
||||
this.modRef = modRef;
|
||||
this.heapModel = heapModel;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -134,7 +137,7 @@ public class HeapReachingDefs {
|
|||
if (VERBOSE) {
|
||||
System.err.println("Solved. ");
|
||||
}
|
||||
return makeResult(solver, domain, node, new DelegatingExtendedHeapModel(pa.getHeapModel()), pa, mod, cfg,
|
||||
return makeResult(solver, domain, node, heapModel, pa, mod, cfg,
|
||||
ssaInstructionIndex2Statement, exclusions, cg);
|
||||
}
|
||||
|
||||
|
@ -478,8 +481,6 @@ public class HeapReachingDefs {
|
|||
|
||||
private final PointerAnalysis pa;
|
||||
|
||||
private final ExtendedHeapModel h;
|
||||
|
||||
private final Map<Integer, NormalStatement> ssaInstructionIndex2Statement;
|
||||
|
||||
private final HeapExclusions exclusions;
|
||||
|
@ -496,7 +497,6 @@ public class HeapReachingDefs {
|
|||
this.cfg = cfg;
|
||||
this.domain = domain;
|
||||
this.pa = pa;
|
||||
this.h = new DelegatingExtendedHeapModel(pa.getHeapModel());
|
||||
this.ssaInstructionIndex2Statement = ssaInstructionIndex2Statement;
|
||||
this.exclusions = exclusions;
|
||||
initHeapReturnCaller();
|
||||
|
@ -606,7 +606,7 @@ public class HeapReachingDefs {
|
|||
}
|
||||
return heapReturnCaller.getRelated(domainIndex);
|
||||
} else {
|
||||
Collection<PointerKey> gen = modRef.getMod(node, h, pa, s, exclusions);
|
||||
Collection<PointerKey> gen = modRef.getMod(node, heapModel, pa, s, exclusions);
|
||||
if (gen.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
|
@ -638,7 +638,7 @@ public class HeapReachingDefs {
|
|||
if (s == null) {
|
||||
return null;
|
||||
} else {
|
||||
Collection<PointerKey> mod = modRef.getMod(node, h, pa, s, exclusions);
|
||||
Collection<PointerKey> mod = modRef.getMod(node, heapModel, pa, s, exclusions);
|
||||
if (mod.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
|
@ -659,7 +659,7 @@ public class HeapReachingDefs {
|
|||
@Override
|
||||
public boolean accepts(Object o) {
|
||||
Statement s = (Statement) o;
|
||||
Collection m = getMod(s, node, h, pa, exclusions);
|
||||
Collection m = getMod(s, node, heapModel, pa, exclusions);
|
||||
for (PointerKey k : kill) {
|
||||
if (m.contains(k)) {
|
||||
return true;
|
||||
|
|
|
@ -147,7 +147,7 @@ public class PDG implements NumberedGraph<Statement> {
|
|||
}
|
||||
this.cg = cg;
|
||||
this.node = node;
|
||||
this.heapModel = pa == null ? null : new DelegatingExtendedHeapModel(pa.getHeapModel());
|
||||
this.heapModel = pa != null? modRef.makeHeapModel(pa): null;
|
||||
this.pa = pa;
|
||||
this.dOptions = dOptions;
|
||||
this.cOptions = cOptions;
|
||||
|
@ -661,7 +661,7 @@ public class PDG implements NumberedGraph<Statement> {
|
|||
};
|
||||
Collection<Statement> relevantStatements = Iterator2Collection.toSet(new FilterIterator<Statement>(iterator(), f));
|
||||
|
||||
Map<Statement, OrdinalSet<Statement>> heapReachingDefs = new HeapReachingDefs(modRef).computeReachingDefs(node, ir, pa, mod,
|
||||
Map<Statement, OrdinalSet<Statement>> heapReachingDefs = new HeapReachingDefs(modRef, heapModel).computeReachingDefs(node, ir, pa, mod,
|
||||
relevantStatements, new HeapExclusions(SetComplement.complement(new SingletonSet(t))), cg);
|
||||
|
||||
for (Statement st : heapReachingDefs.keySet()) {
|
||||
|
|
Loading…
Reference in New Issue