add support for lexical writes
This commit is contained in:
parent
26e7eb50ba
commit
5aa3a16587
|
@ -32,17 +32,23 @@ public abstract class TestTransitiveLexicalAccesses {
|
|||
JSCFABuilder b = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", "simple-lexical.js");
|
||||
CallGraph CG = b.makeCallGraph(b.getOptions());
|
||||
TransitiveLexicalAccesses lexAccesses = TransitiveLexicalAccesses.make(CG, b.getPointerAnalysis());
|
||||
Map<CGNode, OrdinalSet<Pair<CGNode, String>>> result = lexAccesses.computeLexVarsRead();
|
||||
for (CGNode n : result.keySet()) {
|
||||
Map<CGNode, OrdinalSet<Pair<CGNode, String>>> readResult = lexAccesses.computeLexVarsRead();
|
||||
Map<CGNode, OrdinalSet<Pair<CGNode, String>>> writeResult = lexAccesses.computeLexVarsWritten();
|
||||
for (CGNode n : readResult.keySet()) {
|
||||
if (n.toString().contains("Node: <Code body of function Ltests/simple-lexical.js/outer/inner>")) {
|
||||
// function "inner" reads exactly x and z
|
||||
OrdinalSet<Pair<CGNode, String>> readVars = result.get(n);
|
||||
OrdinalSet<Pair<CGNode, String>> readVars = readResult.get(n);
|
||||
Assert.assertEquals(2, readVars.size());
|
||||
Assert.assertEquals("[[Node: <Code body of function Ltests/simple-lexical.js/outer> Context: Everywhere,x], [Node: <Code body of function Ltests/simple-lexical.js/outer> Context: Everywhere,z]]", readVars.toString());
|
||||
// writes x and z as well
|
||||
OrdinalSet<Pair<CGNode, String>> writtenVars = writeResult.get(n);
|
||||
Assert.assertEquals(2, writtenVars.size());
|
||||
Assert.assertEquals("[[Node: <Code body of function Ltests/simple-lexical.js/outer> Context: Everywhere,x], [Node: <Code body of function Ltests/simple-lexical.js/outer> Context: Everywhere,z]]", writtenVars.toString());
|
||||
|
||||
}
|
||||
if (n.toString().contains("Node: <Code body of function Ltests/simple-lexical.js/outer/inner2>")) {
|
||||
// function "inner3" reads exactly innerName, inner3, and x and z via callees
|
||||
OrdinalSet<Pair<CGNode, String>> readVars = result.get(n);
|
||||
OrdinalSet<Pair<CGNode, String>> readVars = readResult.get(n);
|
||||
Assert.assertEquals(4, readVars.size());
|
||||
Assert.assertEquals("[[Node: <Code body of function Ltests/simple-lexical.js/outer> Context: Everywhere,inner3], [Node: <Code body of function Ltests/simple-lexical.js/outer> Context: Everywhere,innerName], [Node: <Code body of function Ltests/simple-lexical.js/outer> Context: Everywhere,x], [Node: <Code body of function Ltests/simple-lexical.js/outer> Context: Everywhere,z]]", readVars.toString());
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import java.util.Map;
|
|||
import com.ibm.wala.cast.ipa.callgraph.ScopeMappingInstanceKeys.ScopeMappingInstanceKey;
|
||||
import com.ibm.wala.cast.ir.ssa.AstLexicalAccess.Access;
|
||||
import com.ibm.wala.cast.ir.ssa.AstLexicalRead;
|
||||
import com.ibm.wala.cast.ir.ssa.AstLexicalWrite;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraphTransitiveClosure;
|
||||
|
@ -58,17 +59,23 @@ public class TransitiveLexicalAccesses {
|
|||
}
|
||||
|
||||
public Map<CGNode, OrdinalSet<Pair<CGNode, String>>> computeLexVarsRead() {
|
||||
Map<CGNode, Collection<Pair<CGNode, String>>> scan = scanForLexReads();
|
||||
return CallGraphTransitiveClosure.transitiveClosure(cg, scan);
|
||||
}
|
||||
|
||||
private Map<CGNode, Collection<Pair<CGNode, String>>> scanForLexReads() {
|
||||
return CallGraphTransitiveClosure.collectNodeResults(cg, new Function<CGNode, Collection<Pair<CGNode,String>>>() {
|
||||
|
||||
Map<CGNode, Collection<Pair<CGNode, String>>> scan = CallGraphTransitiveClosure.collectNodeResults(cg, new Function<CGNode, Collection<Pair<CGNode,String>>>() {
|
||||
|
||||
public Collection<Pair<CGNode, String>> apply(CGNode n) {
|
||||
return scanNodeForLexReads(n);
|
||||
}
|
||||
});
|
||||
return CallGraphTransitiveClosure.transitiveClosure(cg, scan);
|
||||
}
|
||||
|
||||
public Map<CGNode, OrdinalSet<Pair<CGNode, String>>> computeLexVarsWritten() {
|
||||
Map<CGNode, Collection<Pair<CGNode, String>>> scan = CallGraphTransitiveClosure.collectNodeResults(cg, new Function<CGNode, Collection<Pair<CGNode,String>>>() {
|
||||
|
||||
public Collection<Pair<CGNode, String>> apply(CGNode n) {
|
||||
return scanNodeForLexWrites(n);
|
||||
}
|
||||
});
|
||||
return CallGraphTransitiveClosure.transitiveClosure(cg, scan);
|
||||
}
|
||||
|
||||
protected Collection<Pair<CGNode, String>> scanNodeForLexReads(CGNode n) {
|
||||
|
@ -88,6 +95,23 @@ public class TransitiveLexicalAccesses {
|
|||
return result;
|
||||
}
|
||||
|
||||
protected Collection<Pair<CGNode, String>> scanNodeForLexWrites(CGNode n) {
|
||||
Collection<Pair<CGNode, String>> result = HashSetFactory.make();
|
||||
IR ir = n.getIR();
|
||||
if (ir != null) {
|
||||
for (SSAInstruction instr: Iterator2Iterable.make(ir.iterateNormalInstructions())) {
|
||||
if (instr instanceof AstLexicalWrite) {
|
||||
AstLexicalWrite write = (AstLexicalWrite) instr;
|
||||
for (Access a : write.getAccesses()) {
|
||||
Pair<String, String> nameAndDefiner = a.getName();
|
||||
result.addAll(getNodeNamePairsForAccess(n, nameAndDefiner));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Collection<Pair<CGNode, String>> getNodeNamePairsForAccess(CGNode n, Pair<String, String> nameAndDefiner) {
|
||||
Collection<Pair<CGNode, String>> result = HashSetFactory.make();
|
||||
// use scope-mapping instance keys in pointer analysis. may need a different
|
||||
|
|
Loading…
Reference in New Issue