Skip to content

Commit 111de26

Browse files
authoredOct 18, 2023
fix(es/minifier): Abort seq inliner if b can short-circuit (#8128)
**Related issue:** - Closes #8119
1 parent 736831c commit 111de26

File tree

13 files changed

+464
-3
lines changed

13 files changed

+464
-3
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{
2+
"jsc": {
3+
"parser": {
4+
"syntax": "ecmascript",
5+
"jsx": false
6+
},
7+
"target": "es2022",
8+
"loose": false,
9+
"minify": {
10+
"compress": {
11+
"arguments": false,
12+
"arrows": true,
13+
"booleans": true,
14+
"booleans_as_integers": false,
15+
"collapse_vars": true,
16+
"comparisons": true,
17+
"computed_props": true,
18+
"conditionals": true,
19+
"dead_code": true,
20+
"directives": true,
21+
"drop_console": false,
22+
"drop_debugger": true,
23+
"evaluate": true,
24+
"expression": false,
25+
"hoist_funs": false,
26+
"hoist_props": true,
27+
"hoist_vars": false,
28+
"if_return": true,
29+
"join_vars": true,
30+
"keep_classnames": false,
31+
"keep_fargs": true,
32+
"keep_fnames": false,
33+
"keep_infinity": false,
34+
"loops": true,
35+
"negate_iife": true,
36+
"properties": true,
37+
"reduce_funcs": false,
38+
"reduce_vars": false,
39+
"side_effects": true,
40+
"switches": true,
41+
"typeofs": true,
42+
"unsafe": false,
43+
"unsafe_arrows": false,
44+
"unsafe_comps": false,
45+
"unsafe_Function": false,
46+
"unsafe_math": false,
47+
"unsafe_symbols": false,
48+
"unsafe_methods": false,
49+
"unsafe_proto": false,
50+
"unsafe_regexp": false,
51+
"unsafe_undefined": false,
52+
"unused": true,
53+
"const_to_let": true,
54+
"pristine_globals": true,
55+
"passes": 2
56+
},
57+
"mangle": false
58+
}
59+
},
60+
"module": {
61+
"type": "es6"
62+
},
63+
"minify": false,
64+
"isModule": true
65+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
const myArr = [];
2+
// function with side effect
3+
function foo(arr) {
4+
arr.push('foo');
5+
return 'foo';
6+
}
7+
let a;
8+
9+
if (Math.random() > 1.00000) {
10+
a = true;
11+
}
12+
13+
// the function call below should always run
14+
// regardless of whether `a` is `undefined`
15+
let b = foo(myArr);
16+
17+
// const seems to keep this line here instead of
18+
// moving it behind the logitcal nullish assignment
19+
// const b = foo(myArr);
20+
21+
a ??= b;
22+
23+
console.log(a);
24+
console.log(myArr);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
const myArr = [];
2+
// function with side effect
3+
function foo(arr) {
4+
arr.push('foo');
5+
return 'foo';
6+
}
7+
let a;
8+
9+
if (Math.random() > -0.1) {
10+
a = true;
11+
}
12+
13+
// the function call below should always run
14+
// regardless of whether `a` is `undefined`
15+
let b = foo(myArr);
16+
17+
// const seems to keep this line here instead of
18+
// moving it behind the logitcal nullish assignment
19+
// const b = foo(myArr);
20+
21+
a ??= b;
22+
23+
console.log(a);
24+
console.log(myArr);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{
2+
"jsc": {
3+
"parser": {
4+
"syntax": "ecmascript",
5+
"jsx": false
6+
},
7+
"target": "es2022",
8+
"loose": false,
9+
"minify": {
10+
"compress": {
11+
"arguments": false,
12+
"arrows": true,
13+
"booleans": true,
14+
"booleans_as_integers": false,
15+
"collapse_vars": true,
16+
"comparisons": true,
17+
"computed_props": true,
18+
"conditionals": true,
19+
"dead_code": true,
20+
"directives": true,
21+
"drop_console": false,
22+
"drop_debugger": true,
23+
"evaluate": true,
24+
"expression": false,
25+
"hoist_funs": false,
26+
"hoist_props": true,
27+
"hoist_vars": false,
28+
"if_return": true,
29+
"join_vars": true,
30+
"keep_classnames": false,
31+
"keep_fargs": true,
32+
"keep_fnames": false,
33+
"keep_infinity": false,
34+
"loops": true,
35+
"negate_iife": true,
36+
"properties": true,
37+
"reduce_funcs": false,
38+
"reduce_vars": false,
39+
"side_effects": true,
40+
"switches": true,
41+
"typeofs": true,
42+
"unsafe": false,
43+
"unsafe_arrows": false,
44+
"unsafe_comps": false,
45+
"unsafe_Function": false,
46+
"unsafe_math": false,
47+
"unsafe_symbols": false,
48+
"unsafe_methods": false,
49+
"unsafe_proto": false,
50+
"unsafe_regexp": false,
51+
"unsafe_undefined": false,
52+
"unused": true,
53+
"const_to_let": true,
54+
"pristine_globals": true,
55+
"passes": 2
56+
},
57+
"mangle": false
58+
}
59+
},
60+
"module": {
61+
"type": "es6"
62+
},
63+
"minify": false,
64+
"isModule": true
65+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
const myArr = [];
2+
// function with side effect
3+
function foo(arr) {
4+
arr.push('foo');
5+
return 'foo';
6+
}
7+
let a;
8+
9+
if (Math.random() > 0.5) {
10+
a = true;
11+
}
12+
13+
// the function call below should always run
14+
// regardless of whether `a` is `undefined`
15+
let b = foo(myArr);
16+
17+
// const seems to keep this line here instead of
18+
// moving it behind the logitcal nullish assignment
19+
// const b = foo(myArr);
20+
21+
a ??= b;
22+
23+
console.log(a);
24+
console.log(myArr);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
let a;
2+
const myArr = [];
3+
Math.random() > 0.5 && (a = !0);
4+
// the function call below should always run
5+
// regardless of whether `a` is `undefined`
6+
let b = (myArr.push('foo'), 'foo');
7+
console.log(// const seems to keep this line here instead of
8+
// moving it behind the logitcal nullish assignment
9+
// const b = foo(myArr);
10+
a ??= b), console.log(myArr);

‎crates/swc_ecma_minifier/src/compress/optimize/sequences.rs

+4
Original file line numberDiff line numberDiff line change
@@ -2489,6 +2489,10 @@ impl Optimizer<'_> {
24892489
/// 1, arr[i]`
24902490
//
24912491
fn should_not_check_rhs_of_assign(&self, a: &Mergable, b: &mut AssignExpr) -> Result<bool, ()> {
2492+
if b.op.may_short_circuit() {
2493+
return Ok(true);
2494+
}
2495+
24922496
if let Some(a_id) = a.id() {
24932497
match a {
24942498
Mergable::Expr(Expr::Assign(AssignExpr { op: op!("="), .. })) => {}

‎crates/swc_ecma_minifier/tests/exec.rs

+164
Original file line numberDiff line numberDiff line change
@@ -10947,3 +10947,167 @@ fn issue_7274() {
1094710947
"#,
1094810948
);
1094910949
}
10950+
10951+
#[test]
10952+
fn issue_8119_1() {
10953+
run_exec_test(
10954+
r#"
10955+
const myArr = [];
10956+
// function with side effect
10957+
function foo(arr) {
10958+
arr.push('foo');
10959+
return 'foo';
10960+
}
10961+
let a;
10962+
10963+
if (Math.random() > 1.1) {
10964+
a = true;
10965+
}
10966+
10967+
// the function call below should always run
10968+
// regardless of whether `a` is `undefined`
10969+
let b = foo(myArr);
10970+
10971+
// const seems to keep this line here instead of
10972+
// moving it behind the logitcal nullish assignment
10973+
// const b = foo(myArr);
10974+
10975+
a ??= b;
10976+
10977+
console.log(a);
10978+
console.log(myArr);
10979+
"#,
10980+
r#"
10981+
{
10982+
"arguments": false,
10983+
"arrows": true,
10984+
"booleans": true,
10985+
"booleans_as_integers": false,
10986+
"collapse_vars": true,
10987+
"comparisons": true,
10988+
"computed_props": true,
10989+
"conditionals": true,
10990+
"dead_code": true,
10991+
"directives": true,
10992+
"drop_console": false,
10993+
"drop_debugger": true,
10994+
"evaluate": true,
10995+
"expression": false,
10996+
"hoist_funs": false,
10997+
"hoist_props": true,
10998+
"hoist_vars": false,
10999+
"if_return": true,
11000+
"join_vars": true,
11001+
"keep_classnames": false,
11002+
"keep_fargs": true,
11003+
"keep_fnames": false,
11004+
"keep_infinity": false,
11005+
"loops": true,
11006+
"negate_iife": true,
11007+
"properties": true,
11008+
"reduce_funcs": false,
11009+
"reduce_vars": false,
11010+
"side_effects": true,
11011+
"switches": true,
11012+
"typeofs": true,
11013+
"unsafe": false,
11014+
"unsafe_arrows": false,
11015+
"unsafe_comps": false,
11016+
"unsafe_Function": false,
11017+
"unsafe_math": false,
11018+
"unsafe_symbols": false,
11019+
"unsafe_methods": false,
11020+
"unsafe_proto": false,
11021+
"unsafe_regexp": false,
11022+
"unsafe_undefined": false,
11023+
"unused": true,
11024+
"const_to_let": true,
11025+
"pristine_globals": true,
11026+
"passes": 2
11027+
}
11028+
"#,
11029+
false,
11030+
);
11031+
}
11032+
11033+
#[test]
11034+
fn issue_8119_2() {
11035+
run_exec_test(
11036+
r#"
11037+
const myArr = [];
11038+
// function with side effect
11039+
function foo(arr) {
11040+
arr.push('foo');
11041+
return 'foo';
11042+
}
11043+
let a;
11044+
11045+
if (Math.random() > -0.1) {
11046+
a = true;
11047+
}
11048+
11049+
// the function call below should always run
11050+
// regardless of whether `a` is `undefined`
11051+
let b = foo(myArr);
11052+
11053+
// const seems to keep this line here instead of
11054+
// moving it behind the logitcal nullish assignment
11055+
// const b = foo(myArr);
11056+
11057+
a ??= b;
11058+
11059+
console.log(a);
11060+
console.log(myArr);
11061+
"#,
11062+
r#"
11063+
{
11064+
"arguments": false,
11065+
"arrows": true,
11066+
"booleans": true,
11067+
"booleans_as_integers": false,
11068+
"collapse_vars": true,
11069+
"comparisons": true,
11070+
"computed_props": true,
11071+
"conditionals": true,
11072+
"dead_code": true,
11073+
"directives": true,
11074+
"drop_console": false,
11075+
"drop_debugger": true,
11076+
"evaluate": true,
11077+
"expression": false,
11078+
"hoist_funs": false,
11079+
"hoist_props": true,
11080+
"hoist_vars": false,
11081+
"if_return": true,
11082+
"join_vars": true,
11083+
"keep_classnames": false,
11084+
"keep_fargs": true,
11085+
"keep_fnames": false,
11086+
"keep_infinity": false,
11087+
"loops": true,
11088+
"negate_iife": true,
11089+
"properties": true,
11090+
"reduce_funcs": false,
11091+
"reduce_vars": false,
11092+
"side_effects": true,
11093+
"switches": true,
11094+
"typeofs": true,
11095+
"unsafe": false,
11096+
"unsafe_arrows": false,
11097+
"unsafe_comps": false,
11098+
"unsafe_Function": false,
11099+
"unsafe_math": false,
11100+
"unsafe_symbols": false,
11101+
"unsafe_methods": false,
11102+
"unsafe_proto": false,
11103+
"unsafe_regexp": false,
11104+
"unsafe_undefined": false,
11105+
"unused": true,
11106+
"const_to_let": true,
11107+
"pristine_globals": true,
11108+
"passes": 2
11109+
}
11110+
"#,
11111+
false,
11112+
);
11113+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"arguments": false,
3+
"arrows": true,
4+
"booleans": true,
5+
"booleans_as_integers": false,
6+
"collapse_vars": true,
7+
"comparisons": true,
8+
"computed_props": true,
9+
"conditionals": true,
10+
"dead_code": true,
11+
"directives": true,
12+
"drop_console": false,
13+
"drop_debugger": true,
14+
"evaluate": true,
15+
"expression": false,
16+
"hoist_funs": false,
17+
"hoist_props": true,
18+
"hoist_vars": false,
19+
"if_return": true,
20+
"join_vars": true,
21+
"keep_classnames": false,
22+
"keep_fargs": true,
23+
"keep_fnames": false,
24+
"keep_infinity": false,
25+
"loops": true,
26+
"negate_iife": true,
27+
"properties": true,
28+
"reduce_funcs": false,
29+
"reduce_vars": false,
30+
"side_effects": true,
31+
"switches": true,
32+
"typeofs": true,
33+
"unsafe": false,
34+
"unsafe_arrows": false,
35+
"unsafe_comps": false,
36+
"unsafe_Function": false,
37+
"unsafe_math": false,
38+
"unsafe_symbols": false,
39+
"unsafe_methods": false,
40+
"unsafe_proto": false,
41+
"unsafe_regexp": false,
42+
"unsafe_undefined": false,
43+
"unused": true,
44+
"const_to_let": true,
45+
"pristine_globals": true,
46+
"passes": 2
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
const myArr = [];
2+
// function with side effect
3+
function foo(arr) {
4+
arr.push('foo');
5+
return 'foo';
6+
}
7+
let a;
8+
9+
if (Math.random() > 0.5) {
10+
a = true;
11+
}
12+
13+
// the function call below should always run
14+
// regardless of whether `a` is `undefined`
15+
let b = foo(myArr);
16+
17+
// const seems to keep this line here instead of
18+
// moving it behind the logitcal nullish assignment
19+
// const b = foo(myArr);
20+
21+
a ??= b;
22+
23+
console.log(a);
24+
console.log(myArr);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
let a;
2+
const myArr = [];
3+
function foo(arr) {
4+
return arr.push('foo'), 'foo';
5+
}
6+
Math.random() > 0.5 && (a = !0);
7+
let b = foo(myArr);
8+
a ??= b;
9+
console.log(a);
10+
console.log(myArr);

‎crates/swc_ecma_minifier/tests/passing.txt

+3
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,9 @@ hoist_props/issue_3071_2/input.js
744744
hoist_props/issue_3071_2_toplevel/input.js
745745
hoist_props/issue_3071_3/input.js
746746
hoist_props/single_use/input.js
747+
hoist_props/toplevel_const/input.js
748+
hoist_props/toplevel_let/input.js
749+
hoist_props/toplevel_var/input.js
747750
hoist_vars/issue_2295/input.js
748751
hoist_vars/regression_toplevel_args/input.js
749752
hoist_vars/sequences/input.js

‎crates/swc_ecma_minifier/tests/postponed.txt

-3
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,6 @@ hoist_props/name_collision_1/input.js
4040
hoist_props/name_collision_2/input.js
4141
hoist_props/name_collision_3/input.js
4242
hoist_props/new_this/input.js
43-
hoist_props/toplevel_const/input.js
44-
hoist_props/toplevel_let/input.js
45-
hoist_props/toplevel_var/input.js
4643
hoist_props/undefined_key/input.js
4744
ie8/do_screw_try_catch_undefined/input.js
4845
ie8/dont_screw_try_catch/input.js

1 commit comments

Comments
 (1)

github-actions[bot] commented on Oct 18, 2023

@github-actions[bot]

Benchmark

Benchmark suite Current: 111de26 Previous: 4f67794 Ratio
es/full/bugs-1 288829 ns/iter (± 4729) 285618 ns/iter (± 6329) 1.01
es/full/minify/libraries/antd 1389036540 ns/iter (± 21284821) 1386313980 ns/iter (± 24822725) 1.00
es/full/minify/libraries/d3 294138948 ns/iter (± 3409382) 289848387 ns/iter (± 2129801) 1.01
es/full/minify/libraries/echarts 1109978388 ns/iter (± 7166441) 1103835486 ns/iter (± 8002603) 1.01
es/full/minify/libraries/jquery 88689893 ns/iter (± 223944) 88444329 ns/iter (± 131550) 1.00
es/full/minify/libraries/lodash 103844115 ns/iter (± 205738) 103694449 ns/iter (± 401752) 1.00
es/full/minify/libraries/moment 52339031 ns/iter (± 105814) 52299663 ns/iter (± 555346) 1.00
es/full/minify/libraries/react 18844953 ns/iter (± 60064) 18875043 ns/iter (± 75554) 1.00
es/full/minify/libraries/terser 228399108 ns/iter (± 325412) 230926211 ns/iter (± 1411456) 0.99
es/full/minify/libraries/three 409129572 ns/iter (± 3074984) 406505582 ns/iter (± 1425320) 1.01
es/full/minify/libraries/typescript 2760432748 ns/iter (± 14531611) 2759524618 ns/iter (± 13642008) 1.00
es/full/minify/libraries/victory 590763185 ns/iter (± 4211196) 598056874 ns/iter (± 11703653) 0.99
es/full/minify/libraries/vue 126254991 ns/iter (± 968542) 125107901 ns/iter (± 646092) 1.01
es/full/codegen/es3 34082 ns/iter (± 92) 34981 ns/iter (± 323) 0.97
es/full/codegen/es5 34171 ns/iter (± 128) 35082 ns/iter (± 136) 0.97
es/full/codegen/es2015 34093 ns/iter (± 133) 35106 ns/iter (± 161) 0.97
es/full/codegen/es2016 33986 ns/iter (± 148) 35030 ns/iter (± 180) 0.97
es/full/codegen/es2017 34115 ns/iter (± 97) 35077 ns/iter (± 203) 0.97
es/full/codegen/es2018 34052 ns/iter (± 214) 34867 ns/iter (± 218) 0.98
es/full/codegen/es2019 34122 ns/iter (± 132) 35128 ns/iter (± 97) 0.97
es/full/codegen/es2020 34160 ns/iter (± 81) 35152 ns/iter (± 168) 0.97
es/full/all/es3 175675957 ns/iter (± 684933) 178297141 ns/iter (± 1215853) 0.99
es/full/all/es5 168845996 ns/iter (± 1550552) 170952382 ns/iter (± 1087977) 0.99
es/full/all/es2015 127673298 ns/iter (± 985543) 129037936 ns/iter (± 880047) 0.99
es/full/all/es2016 126569701 ns/iter (± 503674) 128931320 ns/iter (± 823433) 0.98
es/full/all/es2017 125724545 ns/iter (± 606938) 127864302 ns/iter (± 698819) 0.98
es/full/all/es2018 123594957 ns/iter (± 631930) 124681982 ns/iter (± 613298) 0.99
es/full/all/es2019 122743563 ns/iter (± 1066059) 125025589 ns/iter (± 731101) 0.98
es/full/all/es2020 119250751 ns/iter (± 890148) 121492810 ns/iter (± 763908) 0.98
es/full/parser 561468 ns/iter (± 3541) 562089 ns/iter (± 3815) 1.00
es/full/base/fixer 18690 ns/iter (± 180) 18552 ns/iter (± 137) 1.01
es/full/base/resolver_and_hygiene 83334 ns/iter (± 239) 82925 ns/iter (± 172) 1.00

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.