From 5eba486d34e82e61f3b0f22a726972899b59cd1e Mon Sep 17 00:00:00 2001 From: Max Schaefer Date: Mon, 28 Jan 2019 12:29:47 +0000 Subject: [PATCH] JavaScript: Clear per-function CFG caches after each function. --- .../com/semmle/js/extractor/CFGExtractor.java | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/javascript/extractor/src/com/semmle/js/extractor/CFGExtractor.java b/javascript/extractor/src/com/semmle/js/extractor/CFGExtractor.java index 1edee6882d2..eccd0aa2dd7 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/CFGExtractor.java +++ b/javascript/extractor/src/com/semmle/js/extractor/CFGExtractor.java @@ -774,13 +774,13 @@ public class CFGExtractor { } // associate statements with their (direct or indirect) labels - private final Map> loopLabels = new LinkedHashMap>(); + private Map> loopLabels = new LinkedHashMap>(); // cache the set of normal control flow successors - private final Map followingCache = new LinkedHashMap(); + private Map followingCache = new LinkedHashMap(); // map from a node in a chain of property accesses or calls to the successor info for the first node in the chain - private final Map chainRootSuccessors = new LinkedHashMap(); + private Map chainRootSuccessors = new LinkedHashMap(); /** * Generate entry node. @@ -1031,6 +1031,16 @@ public class CFGExtractor { @Override public Void visit(IFunction nd, SuccessorInfo i) { + // save per-function caches + Map> oldLoopLabels = loopLabels; + Map oldFollowingCache = followingCache; + Map oldChainRootSuccessors = chainRootSuccessors; + + // clear caches + loopLabels = new LinkedHashMap<>(); + followingCache = new LinkedHashMap<>(); + chainRootSuccessors = new LinkedHashMap<>(); + if (nd instanceof FunctionDeclaration && nd.hasDeclareKeyword()) { // All 'declared' statements have a no-op CFG node, but their children should // not be processed. @@ -1039,6 +1049,12 @@ public class CFGExtractor { } buildFunctionCreation(nd, i); buildFunctionBody(nd); + + // restore caches + loopLabels = oldLoopLabels; + followingCache = oldFollowingCache; + chainRootSuccessors = oldChainRootSuccessors; + return null; }