Skip to content

Commit 7f4facc

Browse files
authored
Merge pull request github#18661 from asgerf/js/hoist-in-block
JS: Hoist function declarations to the top of a block statement
2 parents 83ccdb7 + 6ae06ae commit 7f4facc

File tree

72 files changed

+159
-135
lines changed

Some content is hidden

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

72 files changed

+159
-135
lines changed

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

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -586,14 +586,6 @@ private static List<Identifier> of(List<Statement> body) {
586586
public static List<Identifier> of(Program p) {
587587
return of(p.getBody());
588588
}
589-
590-
public static List<Identifier> of(IFunction fn) {
591-
Node body = fn.getBody();
592-
if (body instanceof BlockStatement) return of(((BlockStatement) body).getBody());
593-
// if the body of the function is missing or is an expression, then there are
594-
// no hoisted functions
595-
return Collections.emptyList();
596-
}
597589
}
598590

599591
/**
@@ -1096,8 +1088,6 @@ private void buildFunctionBody(IFunction nd) {
10961088
if (nd.hasRest()) paramsAndDefaults.add((Expression) nd.getRest());
10971089

10981090
Node entry = getEntryNode(nd);
1099-
List<Identifier> fns = HoistedFunDecls.of(nd);
1100-
hoistedFns.addAll(fns);
11011091

11021092
// if this is the constructor of a class without a superclass, we need to
11031093
// initialise all fields before running the body of the constructor
@@ -1117,7 +1107,7 @@ private void buildFunctionBody(IFunction nd) {
11171107
if (firstField != null) fst = Collections.singleton(First.of(firstField));
11181108
fst =
11191109
visitSequence(
1120-
nd instanceof FunctionDeclaration ? null : nd.getId(), paramsAndDefaults, fns, fst);
1110+
nd instanceof FunctionDeclaration ? null : nd.getId(), paramsAndDefaults, fst);
11211111
writeSuccessors(entry, fst);
11221112

11231113
this.ctxt.pop();
@@ -1255,9 +1245,12 @@ public Void visit(Literal nd, SuccessorInfo i) {
12551245

12561246
@Override
12571247
public Void visit(BlockStatement nd, SuccessorInfo i) {
1258-
if (nd.getBody().isEmpty()) writeSuccessors(nd, i.getAllSuccessors());
1259-
else writeSuccessor(nd, First.of(nd.getBody().get(0)));
1260-
visitSequence(nd.getBody(), i.getAllSuccessors());
1248+
// Hoist function declarations in a block statement to the top of the block.
1249+
// This reflects non-standard behaviour implemented by most engines.
1250+
// See also: ECMAScript "B.3.2 Block-Level Function Declarations Web Legacy Compatibility Semantics".
1251+
List<Identifier> hoisted = HoistedFunDecls.of(nd.getBody());
1252+
hoistedFns.addAll(hoisted);
1253+
writeSuccessors(nd, visitSequence(hoisted, nd.getBody(), i.getAllSuccessors()));
12611254
return null;
12621255
}
12631256

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public class Main {
4242
* A version identifier that should be updated every time the extractor changes in such a way that
4343
* it may produce different tuples for the same file under the same {@link ExtractorConfig}.
4444
*/
45-
public static final String EXTRACTOR_VERSION = "2025-01-21";
45+
public static final String EXTRACTOR_VERSION = "2025-02-03";
4646

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

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,12 +163,12 @@ hasLocation(#20044,#20028)
163163
#20045=*
164164
exit_cfg_node(#20045,#20030)
165165
hasLocation(#20045,#20028)
166-
successor(#20035,#20036)
167166
successor(#20036,#20038)
168167
successor(#20040,#20039)
169168
successor(#20039,#20037)
170169
successor(#20038,#20040)
171170
successor(#20037,#20045)
171+
successor(#20035,#20036)
172172
successor(#20033,#20035)
173173
successor(#20044,#20033)
174174
successor(#20029,#20030)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,12 +184,12 @@ hasLocation(#20050,#20034)
184184
#20051=*
185185
exit_cfg_node(#20051,#20036)
186186
hasLocation(#20051,#20034)
187-
successor(#20041,#20042)
188187
successor(#20042,#20044)
189188
successor(#20046,#20045)
190189
successor(#20045,#20043)
191190
successor(#20044,#20046)
192191
successor(#20043,#20051)
192+
successor(#20041,#20042)
193193
successor(#20039,#20041)
194194
successor(#20050,#20039)
195195
successor(#20035,#20036)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,6 @@ exit_cfg_node(#20215,#20188)
671671
#20216=@"loc,{#10000},16,4,16,3"
672672
locations_default(#20216,#10000,16,4,16,3)
673673
hasLocation(#20215,#20216)
674-
successor(#20192,#20194)
675674
successor(#20203,#20205)
676675
successor(#20205,#20215)
677676
successor(#20198,#20202)
@@ -680,6 +679,7 @@ successor(#20207,#20203)
680679
successor(#20200,#20209)
681680
successor(#20194,#20196)
682681
successor(#20196,#20198)
682+
successor(#20192,#20194)
683683
successor(#20213,#20192)
684684
successor(#20187,#20188)
685685
successor(#20185,#20180)
@@ -729,9 +729,9 @@ exit_cfg_node(#20227,#20146)
729729
#20228=@"loc,{#10000},4,4,4,3"
730730
locations_default(#20228,#10000,4,4,4,3)
731731
hasLocation(#20227,#20228)
732-
successor(#20150,#20152)
733732
successor(#20152,#20154)
734733
successor(#20154,#20227)
734+
successor(#20150,#20152)
735735
successor(#20225,#20158)
736736
successor(#20145,#20146)
737737
successor(#20143,#20164)

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1425,30 +1425,30 @@ successor(#20455,#20457)
14251425
successor(#20457,#20461)
14261426
successor(#20432,#20434)
14271427
successor(#20434,#20436)
1428-
successor(#20436,#20438)
14291428
successor(#20438,#20442)
14301429
successor(#20442,#20440)
14311430
successor(#20440,#20443)
1431+
successor(#20436,#20438)
14321432
successor(#20414,#20416)
1433-
successor(#20416,#20420)
14341433
successor(#20420,#20418)
14351434
successor(#20418,#20422)
14361435
successor(#20418,#20432)
14371436
successor(#20424,#20418)
14381437
successor(#20422,#20424)
1438+
successor(#20416,#20420)
14391439
successor(#20425,#20429)
14401440
successor(#20430,#20432)
14411441
successor(#20429,#20430)
14421442
successor(#20392,#20394)
14431443
successor(#20394,#20412)
14441444
successor(#20396,#20400)
1445-
successor(#20401,#20403)
14461445
successor(#20403,#20409)
14471446
successor(#20411,#20407)
14481447
successor(#20409,#20411)
14491448
successor(#20407,#20412)
14501449
successor(#20407,#20405)
14511450
successor(#20405,#20412)
1451+
successor(#20401,#20403)
14521452
successor(#20400,#20401)
14531453
successor(#20412,#20414)
14541454
successor(#20371,#20392)
@@ -1462,7 +1462,6 @@ exit_cfg_node(#20468,#20371)
14621462
#20469=@"loc,{#10000},18,2,18,1"
14631463
locations_default(#20469,#10000,18,2,18,1)
14641464
hasLocation(#20468,#20469)
1465-
successor(#20379,#20383)
14661465
successor(#20383,#20381)
14671466
successor(#20381,#20384)
14681467
successor(#20381,#20468)
@@ -1481,6 +1480,7 @@ successor(#20391,#20381)
14811480
successor(#20384,#20387)
14821481
successor(#20387,#20386)
14831482
successor(#20386,#20388)
1483+
successor(#20379,#20383)
14841484
successor(#20377,#20379)
14851485
successor(#20466,#20377)
14861486
successor(#20365,#20367)
@@ -1504,7 +1504,6 @@ exit_cfg_node(#20475,#20322)
15041504
#20476=@"loc,{#10000},10,2,10,1"
15051505
locations_default(#20476,#10000,10,2,10,1)
15061506
hasLocation(#20475,#20476)
1507-
successor(#20328,#20330)
15081507
successor(#20356,#20358)
15091508
successor(#20358,#20359)
15101509
successor(#20359,#20361)
@@ -1539,6 +1538,7 @@ successor(#20330,#20334)
15391538
successor(#20335,#20332)
15401539
successor(#20334,#20335)
15411540
successor(#20332,#20336)
1541+
successor(#20328,#20330)
15421542
successor(#20474,#20328)
15431543
successor(#20373,#20322)
15441544
successor(#20324,#20373)

javascript/extractor/tests/es2015/output/trap/array_pattern_with_rest.js.trap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,14 +235,14 @@ hasLocation(#20074,#20072)
235235
#20075=*
236236
exit_cfg_node(#20075,#20051)
237237
hasLocation(#20075,#20048)
238-
successor(#20058,#20060)
239238
successor(#20070,#20068)
240239
successor(#20068,#20075)
241240
successor(#20060,#20067)
242241
successor(#20064,#20066)
243242
successor(#20066,#20062)
244243
successor(#20067,#20064)
245244
successor(#20062,#20070)
245+
successor(#20058,#20060)
246246
successor(#20056,#20058)
247247
successor(#20074,#20056)
248248
successor(#20052,#20051)

javascript/extractor/tests/es2015/output/trap/arrowfn.js.trap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,11 +509,11 @@ exit_cfg_node(#20163,#20143)
509509
#20164=@"loc,{#10000},3,40,3,39"
510510
locations_default(#20164,#10000,3,40,3,39)
511511
hasLocation(#20163,#20164)
512-
successor(#20146,#20148)
513512
successor(#20148,#20152)
514513
successor(#20154,#20150)
515514
successor(#20152,#20154)
516515
successor(#20150,#20163)
516+
successor(#20146,#20148)
517517
successor(#20161,#20146)
518518
successor(#20141,#20143)
519519
successor(#20139,#20160)

javascript/extractor/tests/es2015/output/trap/class_accessors.js.trap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -434,14 +434,14 @@ exit_cfg_node(#20134,#20101)
434434
#20135=@"loc,{#10000},7,4,7,3"
435435
locations_default(#20135,#10000,7,4,7,3)
436436
hasLocation(#20134,#20135)
437-
successor(#20107,#20109)
438437
successor(#20109,#20115)
439438
successor(#20119,#20117)
440439
successor(#20117,#20111)
441440
successor(#20116,#20113)
442441
successor(#20115,#20116)
443442
successor(#20113,#20119)
444443
successor(#20111,#20134)
444+
successor(#20107,#20109)
445445
successor(#20105,#20107)
446446
successor(#20132,#20105)
447447
successor(#20100,#20101)
@@ -457,11 +457,11 @@ exit_cfg_node(#20138,#20086)
457457
#20139=@"loc,{#10000},4,4,4,3"
458458
locations_default(#20139,#10000,4,4,4,3)
459459
hasLocation(#20138,#20139)
460-
successor(#20090,#20096)
461460
successor(#20097,#20094)
462461
successor(#20096,#20097)
463462
successor(#20094,#20092)
464463
successor(#20092,#20138)
464+
successor(#20090,#20096)
465465
successor(#20136,#20090)
466466
successor(#20085,#20086)
467467
successor(#20083,#20100)

javascript/extractor/tests/es2015/output/trap/class_ctor.js.trap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,13 +246,13 @@ exit_cfg_node(#20076,#20054)
246246
#20077=@"loc,{#10000},4,4,4,3"
247247
locations_default(#20077,#10000,4,4,4,3)
248248
hasLocation(#20076,#20077)
249-
successor(#20060,#20062)
250249
successor(#20062,#20068)
251250
successor(#20070,#20064)
252251
successor(#20069,#20066)
253252
successor(#20068,#20069)
254253
successor(#20066,#20070)
255254
successor(#20064,#20076)
255+
successor(#20060,#20062)
256256
successor(#20058,#20060)
257257
successor(#20074,#20058)
258258
successor(#20053,#20054)

0 commit comments

Comments
 (0)