Skip to content

Commit e195ac9

Browse files
authored
Merge pull request #868 from xiemaisi/js/discard-tokens-early
Approved by esben-semmle
2 parents 32cc7c7 + 7be3336 commit e195ac9

File tree

233 files changed

+67991
-72121
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

233 files changed

+67991
-72121
lines changed

javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -823,7 +823,6 @@ private void extractFunction(IFunction nd, Label key) {
823823

824824
contextManager.leaveContainer();
825825
scopeManager.leaveScope();
826-
lexicalExtractor.emitNumlines(key, nd.getLoc().getStart(), nd.getLoc().getEnd());
827826
}
828827

829828
private void extractParameterDefaultsAndTypes(IFunction nd, Label key, int paramCount) {

javascript/extractor/src/com/semmle/js/extractor/CFGExtractor.java

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -773,14 +773,18 @@ public Finally(SourceLocation loc, BlockStatement body) {
773773
public <Q, A> A accept(Visitor<Q, A> v, Q q) { return null; }
774774
}
775775

776-
// associate statements with their (direct or indirect) labels
777-
private final Map<Statement, Set<String>> loopLabels = new LinkedHashMap<Statement, Set<String>>();
776+
// associate statements with their (direct or indirect) labels;
777+
// per-function cache, cleared after each function
778+
private Map<Statement, Set<String>> loopLabels = new LinkedHashMap<Statement, Set<String>>();
778779

779-
// cache the set of normal control flow successors
780-
private final Map<Node, Object> followingCache = new LinkedHashMap<Node, Object>();
780+
// cache the set of normal control flow successors;
781+
// per-function cache, cleared after each function
782+
private Map<Node, Object> followingCache = new LinkedHashMap<Node, Object>();
781783

782-
// map from a node in a chain of property accesses or calls to the successor info for the first node in the chain
783-
private final Map<Chainable, SuccessorInfo> chainRootSuccessors = new LinkedHashMap<Chainable, SuccessorInfo>();
784+
// map from a node in a chain of property accesses or calls to the successor info
785+
// for the first node in the chain;
786+
// per-function cache, cleared after each function
787+
private Map<Chainable, SuccessorInfo> chainRootSuccessors = new LinkedHashMap<Chainable, SuccessorInfo>();
784788

785789
/**
786790
* Generate entry node.
@@ -1031,6 +1035,16 @@ private void buildFunctionBody(IFunction nd) {
10311035

10321036
@Override
10331037
public Void visit(IFunction nd, SuccessorInfo i) {
1038+
// save per-function caches
1039+
Map<Statement, Set<String>> oldLoopLabels = loopLabels;
1040+
Map<Node, Object> oldFollowingCache = followingCache;
1041+
Map<Chainable, SuccessorInfo> oldChainRootSuccessors = chainRootSuccessors;
1042+
1043+
// clear caches
1044+
loopLabels = new LinkedHashMap<>();
1045+
followingCache = new LinkedHashMap<>();
1046+
chainRootSuccessors = new LinkedHashMap<>();
1047+
10341048
if (nd instanceof FunctionDeclaration && nd.hasDeclareKeyword()) {
10351049
// All 'declared' statements have a no-op CFG node, but their children should
10361050
// not be processed.
@@ -1039,6 +1053,12 @@ public Void visit(IFunction nd, SuccessorInfo i) {
10391053
}
10401054
buildFunctionCreation(nd, i);
10411055
buildFunctionBody(nd);
1056+
1057+
// restore caches
1058+
loopLabels = oldLoopLabels;
1059+
followingCache = oldFollowingCache;
1060+
chainRootSuccessors = oldChainRootSuccessors;
1061+
10421062
return null;
10431063
}
10441064

javascript/extractor/src/com/semmle/js/extractor/JSExtractor.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,14 @@ public Pair<Label, LoCInfo> extract(TextualExtractor textualExtractor,
9494
ASTExtractor scriptExtractor = new ASTExtractor(lexicalExtractor, scopeManager);
9595
toplevelLabel = scriptExtractor.getToplevelLabel();
9696

97-
scriptExtractor.extract(ast, platform, sourceType, toplevelKind);
9897
lexicalExtractor.extractComments(toplevelLabel);
9998
loc = lexicalExtractor.extractLines(parserRes.getSource(), toplevelLabel);
10099
lexicalExtractor.extractTokens(toplevelLabel);
101-
new CFGExtractor(scriptExtractor).extract(ast);
102100
new JSDocExtractor(textualExtractor).extract(lexicalExtractor.getComments());
101+
lexicalExtractor.purge();
102+
103+
scriptExtractor.extract(ast, platform, sourceType, toplevelKind);
104+
new CFGExtractor(scriptExtractor).extract(ast);
103105
} else {
104106
lexicalExtractor = new LexicalExtractor(textualExtractor, new ArrayList<Token>(), new ArrayList<Comment>());
105107
ASTExtractor scriptExtractor = new ASTExtractor(lexicalExtractor, null);

javascript/extractor/src/com/semmle/js/extractor/LexicalExtractor.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ public void extractTokens(Label toplevelKey) {
133133
locationManager.emitNodeLocation(token, key);
134134

135135
// fill in next_token relation
136-
while (j < comments.size() && comments.get(j).getLoc().getEnd().compareTo(token.getLoc().getStart()) < 0)
136+
while (j < comments.size() && comments.get(j).getLoc().getEnd().compareTo(token.getLoc().getStart()) <= 0)
137137
trapwriter.addTuple("next_token", this.trapwriter.localID(comments.get(j++)), key);
138138

139139
// the parser sometimes duplicates tokens; skip the second one by nulling it out
@@ -173,4 +173,12 @@ public void extractComments(Label toplevelKey) {
173173
public String mkToString(SourceElement nd) {
174174
return textualExtractor.mkToString(nd);
175175
}
176+
177+
/**
178+
* Purge token and comments information to reduce heap pressure.
179+
*/
180+
public void purge() {
181+
this.tokens.clear();
182+
this.comments.clear();
183+
}
176184
}

javascript/extractor/src/com/semmle/js/extractor/Main.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public class Main {
4141
* such a way that it may produce different tuples for the same file under the same
4242
* {@link ExtractorConfig}.
4343
*/
44-
public static final String EXTRACTOR_VERSION = "2019-01-17";
44+
public static final String EXTRACTOR_VERSION = "2019-01-29";
4545

4646
public static final Pattern NEWLINE = Pattern.compile("\n");
4747

javascript/extractor/src/com/semmle/js/extractor/test/TrapTests.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import java.nio.charset.Charset;
66
import java.util.ArrayList;
77
import java.util.Arrays;
8-
import java.util.Collections;
98
import java.util.Comparator;
109
import java.util.List;
1110
import java.util.Map.Entry;

javascript/extractor/tests/cfg/output/trap/classexpr1.js.trap

Lines changed: 87 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -9,113 +9,112 @@ hasLocation(#10000,#10002)
99
#20000=@"global_scope"
1010
scopes(#20000,0)
1111
#20001=@"script;{#10000},1,1"
12-
toplevels(#20001,0)
13-
#20002=@"loc,{#10000},1,1,1,10"
14-
locations_default(#20002,#10000,1,1,1,10)
15-
hasLocation(#20001,#20002)
16-
#20003=*
17-
stmts(#20003,2,#20001,0,"!class {};")
18-
hasLocation(#20003,#20002)
19-
stmtContainers(#20003,#20001)
12+
#20002=*
13+
lines(#20002,#20001,"!class {};","")
14+
#20003=@"loc,{#10000},1,1,1,10"
15+
locations_default(#20003,#10000,1,1,1,10)
16+
hasLocation(#20002,#20003)
17+
numlines(#20001,1,1,0)
2018
#20004=*
21-
exprs(#20004,18,#20003,0,"!class {}")
22-
#20005=@"loc,{#10000},1,1,1,9"
23-
locations_default(#20005,#10000,1,1,1,9)
19+
tokeninfo(#20004,8,#20001,0,"!")
20+
#20005=@"loc,{#10000},1,1,1,1"
21+
locations_default(#20005,#10000,1,1,1,1)
2422
hasLocation(#20004,#20005)
25-
enclosingStmt(#20004,#20003)
26-
exprContainers(#20004,#20001)
2723
#20006=*
28-
exprs(#20006,80,#20004,0,"class {}")
29-
#20007=@"loc,{#10000},1,2,1,9"
30-
locations_default(#20007,#10000,1,2,1,9)
24+
tokeninfo(#20006,7,#20001,1,"class")
25+
#20007=@"loc,{#10000},1,2,1,6"
26+
locations_default(#20007,#10000,1,2,1,6)
3127
hasLocation(#20006,#20007)
32-
enclosingStmt(#20006,#20003)
33-
exprContainers(#20006,#20001)
3428
#20008=*
35-
properties(#20008,#20006,2,0,"constructor() {}")
36-
#20009=@"loc,{#10000},1,8,1,7"
37-
locations_default(#20009,#10000,1,8,1,7)
29+
tokeninfo(#20008,8,#20001,2,"{")
30+
#20009=@"loc,{#10000},1,8,1,8"
31+
locations_default(#20009,#10000,1,8,1,8)
3832
hasLocation(#20008,#20009)
3933
#20010=*
40-
exprs(#20010,0,#20008,0,"constructor")
41-
hasLocation(#20010,#20009)
42-
enclosingStmt(#20010,#20003)
43-
exprContainers(#20010,#20001)
44-
literals("constructor","constructor",#20010)
45-
#20011=*
46-
exprs(#20011,9,#20008,1,"() {}")
47-
hasLocation(#20011,#20009)
48-
enclosingStmt(#20011,#20003)
49-
exprContainers(#20011,#20001)
34+
tokeninfo(#20010,8,#20001,3,"}")
35+
#20011=@"loc,{#10000},1,9,1,9"
36+
locations_default(#20011,#10000,1,9,1,9)
37+
hasLocation(#20010,#20011)
5038
#20012=*
51-
scopes(#20012,1)
52-
scopenodes(#20011,#20012)
53-
scopenesting(#20012,#20000)
54-
#20013=@"var;{arguments};{#20012}"
55-
variables(#20013,"arguments",#20012)
56-
isArgumentsObject(#20013)
39+
tokeninfo(#20012,8,#20001,4,";")
40+
#20013=@"loc,{#10000},1,10,1,10"
41+
locations_default(#20013,#10000,1,10,1,10)
42+
hasLocation(#20012,#20013)
5743
#20014=*
58-
stmts(#20014,1,#20011,-2,"{}")
59-
hasLocation(#20014,#20009)
60-
stmtContainers(#20014,#20011)
61-
numlines(#20011,1,0,0)
62-
isMethod(#20008)
63-
#20015=*
64-
lines(#20015,#20001,"!class {};","")
65-
hasLocation(#20015,#20002)
66-
numlines(#20001,1,1,0)
44+
tokeninfo(#20014,0,#20001,5,"")
45+
#20015=@"loc,{#10000},1,11,1,10"
46+
locations_default(#20015,#10000,1,11,1,10)
47+
hasLocation(#20014,#20015)
48+
toplevels(#20001,0)
49+
hasLocation(#20001,#20003)
6750
#20016=*
68-
tokeninfo(#20016,8,#20001,0,"!")
69-
#20017=@"loc,{#10000},1,1,1,1"
70-
locations_default(#20017,#10000,1,1,1,1)
71-
hasLocation(#20016,#20017)
72-
#20018=*
73-
tokeninfo(#20018,7,#20001,1,"class")
74-
#20019=@"loc,{#10000},1,2,1,6"
75-
locations_default(#20019,#10000,1,2,1,6)
76-
hasLocation(#20018,#20019)
77-
#20020=*
78-
tokeninfo(#20020,8,#20001,2,"{")
79-
#20021=@"loc,{#10000},1,8,1,8"
80-
locations_default(#20021,#10000,1,8,1,8)
81-
hasLocation(#20020,#20021)
82-
#20022=*
83-
tokeninfo(#20022,8,#20001,3,"}")
84-
#20023=@"loc,{#10000},1,9,1,9"
85-
locations_default(#20023,#10000,1,9,1,9)
86-
hasLocation(#20022,#20023)
51+
stmts(#20016,2,#20001,0,"!class {};")
52+
hasLocation(#20016,#20003)
53+
stmtContainers(#20016,#20001)
54+
#20017=*
55+
exprs(#20017,18,#20016,0,"!class {}")
56+
#20018=@"loc,{#10000},1,1,1,9"
57+
locations_default(#20018,#10000,1,1,1,9)
58+
hasLocation(#20017,#20018)
59+
enclosingStmt(#20017,#20016)
60+
exprContainers(#20017,#20001)
61+
#20019=*
62+
exprs(#20019,80,#20017,0,"class {}")
63+
#20020=@"loc,{#10000},1,2,1,9"
64+
locations_default(#20020,#10000,1,2,1,9)
65+
hasLocation(#20019,#20020)
66+
enclosingStmt(#20019,#20016)
67+
exprContainers(#20019,#20001)
68+
#20021=*
69+
properties(#20021,#20019,2,0,"constructor() {}")
70+
#20022=@"loc,{#10000},1,8,1,7"
71+
locations_default(#20022,#10000,1,8,1,7)
72+
hasLocation(#20021,#20022)
73+
#20023=*
74+
exprs(#20023,0,#20021,0,"constructor")
75+
hasLocation(#20023,#20022)
76+
enclosingStmt(#20023,#20016)
77+
exprContainers(#20023,#20001)
78+
literals("constructor","constructor",#20023)
8779
#20024=*
88-
tokeninfo(#20024,8,#20001,4,";")
89-
#20025=@"loc,{#10000},1,10,1,10"
90-
locations_default(#20025,#10000,1,10,1,10)
91-
hasLocation(#20024,#20025)
92-
#20026=*
93-
tokeninfo(#20026,0,#20001,5,"")
94-
#20027=@"loc,{#10000},1,11,1,10"
95-
locations_default(#20027,#10000,1,11,1,10)
96-
hasLocation(#20026,#20027)
80+
exprs(#20024,9,#20021,1,"() {}")
81+
hasLocation(#20024,#20022)
82+
enclosingStmt(#20024,#20016)
83+
exprContainers(#20024,#20001)
84+
#20025=*
85+
scopes(#20025,1)
86+
scopenodes(#20024,#20025)
87+
scopenesting(#20025,#20000)
88+
#20026=@"var;{arguments};{#20025}"
89+
variables(#20026,"arguments",#20025)
90+
isArgumentsObject(#20026)
91+
#20027=*
92+
stmts(#20027,1,#20024,-2,"{}")
93+
hasLocation(#20027,#20022)
94+
stmtContainers(#20027,#20024)
95+
isMethod(#20021)
9796
#20028=*
9897
entry_cfg_node(#20028,#20001)
9998
#20029=@"loc,{#10000},1,1,1,0"
10099
locations_default(#20029,#10000,1,1,1,0)
101100
hasLocation(#20028,#20029)
102101
#20030=*
103102
exit_cfg_node(#20030,#20001)
104-
hasLocation(#20030,#20027)
105-
successor(#20003,#20010)
106-
successor(#20011,#20008)
103+
hasLocation(#20030,#20015)
104+
successor(#20016,#20023)
105+
successor(#20024,#20021)
107106
#20031=*
108-
entry_cfg_node(#20031,#20011)
109-
hasLocation(#20031,#20009)
107+
entry_cfg_node(#20031,#20024)
108+
hasLocation(#20031,#20022)
110109
#20032=*
111-
exit_cfg_node(#20032,#20011)
112-
hasLocation(#20032,#20009)
113-
successor(#20014,#20032)
114-
successor(#20031,#20014)
115-
successor(#20010,#20011)
116-
successor(#20008,#20006)
117-
successor(#20006,#20004)
118-
successor(#20004,#20030)
119-
successor(#20028,#20003)
110+
exit_cfg_node(#20032,#20024)
111+
hasLocation(#20032,#20022)
112+
successor(#20027,#20032)
113+
successor(#20031,#20027)
114+
successor(#20023,#20024)
115+
successor(#20021,#20019)
116+
successor(#20019,#20017)
117+
successor(#20017,#20030)
118+
successor(#20028,#20016)
120119
numlines(#10000,1,1,0)
121120
filetype(#10000,"javascript")

0 commit comments

Comments
 (0)