8000 fix(es/minifier): Don't inline a function if we need referential equa… · swc-project/swc@96cec97 · GitHub
[go: up one dir, main page]

Skip to content

Commit 96cec97

Browse files
authored
fix(es/minifier): Don't inline a function if we need referential equality (#4665)
1 parent c5b92a6 commit 96cec97

File tree

10 files changed

+93
-39
lines changed

10 files changed

+93
-39
lines changed

crates/swc/tests/tsc-references/typeofOperatorWithBooleanType_es5.2.minified.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ var objA = new A();
1919
void 0 === BOOLEAN || swcHelpers.typeOf(BOOLEAN), swcHelpers.typeOf(!0), swcHelpers.typeOf({
2020
x: !0,
2121
y: !1
22-
}), swcHelpers.typeOf(objA.a), swcHelpers.typeOf(M.n), swcHelpers.typeOf(!0), swcHelpers.typeOf(A.foo()), swcHelpers.typeOf(void 0 === BOOLEAN ? "undefined" : swcHelpers.typeOf(BOOLEAN)), swcHelpers.typeOf(!0), void 0 === BOOLEAN || swcHelpers.typeOf(BOOLEAN), swcHelpers.typeOf(!0), swcHelpers.typeOf(!0), swcHelpers.typeOf(objA.a), swcHelpers.typeOf(M.n);
22+
}), swcHelpers.typeOf(objA.a), swcHelpers.typeOf(M.n), swcHelpers.typeOf(foo()), swcHelpers.typeOf(A.foo()), swcHelpers.typeOf(void 0 === BOOLEAN ? "undefined" : swcHelpers.typeOf(BOOLEAN)), swcHelpers.typeOf(!0), void 0 === BOOLEAN || swcHelpers.typeOf(BOOLEAN), swcHelpers.typeOf(foo()), swcHelpers.typeOf(!0), swcHelpers.typeOf(objA.a), swcHelpers.typeOf(M.n);
2323
z: void 0 === BOOLEAN || swcHelpers.typeOf(BOOLEAN);
2424
r: swcHelpers.typeOf(foo);
2525
z: swcHelpers.typeOf(!0);

crates/swc/tests/tsc-references/typeofOperatorWithNumberType_es5.2.minified.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ void 0 === NUMBER || swcHelpers.typeOf(NUMBER), swcHelpers.typeOf(NUMBER1), swcH
2828
y: function(n) {
2929
return n;
3030
}
31-
}), swcHelpers.typeOf(objA.a), swcHelpers.typeOf(M.n), swcHelpers.typeOf(NUMBER1[0]), swcHelpers.typeOf(1), swcHelpers.typeOf(A.foo()), swcHelpers.typeOf(NUMBER + NUMBER), swcHelpers.typeOf(void 0 === NUMBER ? "undefined" : swcHelpers.typeOf(NUMBER)), swcHelpers.typeOf(swcHelpers.typeOf(swcHelpers.typeOf(NUMBER + NUMBER))), swcHelpers.typeOf(1), void 0 === NUMBER || swcHelpers.typeOf(NUMBER), swcHelpers.typeOf(NUMBER1), swcHelpers.typeOf(1), swcHelpers.typeOf(objA.a), swcHelpers.typeOf(M.n), swcHelpers.typeOf(objA.a), M.n;
31+
}), swcHelpers.typeOf(objA.a), swcHelpers.typeOf(M.n), swcHelpers.typeOf(NUMBER1[0]), swcHelpers.typeOf(foo()), swcHelpers.typeOf(A.foo()), swcHelpers.typeOf(NUMBER + NUMBER), swcHelpers.typeOf(void 0 === NUMBER ? "undefined" : swcHelpers.typeOf(NUMBER)), swcHelpers.typeOf(swcHelpers.typeOf(swcHelpers.typeOf(NUMBER + NUMBER))), swcHelpers.typeOf(1), void 0 === NUMBER || swcHelpers.typeOf(NUMBER), swcHelpers.typeOf(NUMBER1), swcHelpers.typeOf(foo()), swcHelpers.typeOf(objA.a), swcHelpers.typeOf(M.n), swcHelpers.typeOf(objA.a), M.n;
3232
z: void 0 === NUMBER || swcHelpers.typeOf(NUMBER);
3333
x: swcHelpers.typeOf(NUMBER1);
3434
r: swcHelpers.typeOf(foo);

crates/swc/tests/tsc-references/typeofOperatorWithStringType_es5.2.minified.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ void 0 === STRING || swcHelpers.typeOf(STRING), swcHelpers.typeOf(STRING1), swcH
2828
y: function(s) {
2929
return s;
3030
}
31-
}), swcHelpers.typeOf(objA.a), swcHelpers.typeOf(M.n), swcHelpers.typeOf(STRING1[0]), swcHelpers.typeOf("abc"), swcHelpers.typeOf(A.foo()), swcHelpers.typeOf(STRING + STRING), swcHelpers.typeOf(STRING.charAt(0)), swcHelpers.typeOf(void 0 === STRING ? "undefined" : swcHelpers.typeOf(STRING)), swcHelpers.typeOf(swcHelpers.typeOf(swcHelpers.typeOf(STRING + STRING))), swcHelpers.typeOf(""), void 0 === STRING || swcHelpers.typeOf(STRING), swcHelpers.typeOf(STRING1), swcHelpers.typeOf("abc"), swcHelpers.typeOf(objA.a), M.n;
31+
}), swcHelpers.typeOf(objA.a), swcHelpers.typeOf(M.n), swcHelpers.typeOf(STRING1[0]), swcHelpers.typeOf(foo()), swcHelpers.typeOf(A.foo()), swcHelpers.typeOf(STRING + STRING), swcHelpers.typeOf(STRING.charAt(0)), swcHelpers.typeOf(void 0 === STRING ? "undefined" : swcHelpers.typeOf(STRING)), swcHelpers.typeOf(swcHelpers.typeOf(swcHelpers.typeOf(STRING + STRING))), swcHelpers.typeOf(""), void 0 === STRING || swcHelpers.typeOf(STRING), swcHelpers.typeOf(STRING1), swcHelpers.typeOf(foo()), swcHelpers.typeOf(objA.a), M.n;
3232
z: void 0 === STRING || swcHelpers.typeOf(STRING);
3333
x: swcHelpers.typeOf(STRING1);
3434
r: swcHelpers.typeOf(foo);

crates/swc/tests/tsc-references/variadicTuples1_es2015.2.minified.js

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,6 @@ function curry(f, ...a) {
88
return (...b)=>f(...a, ...b)
99
;
1010
}
11-
function curry2(f, t, u) {
12-
return f(...t, ...u);
13-
}
14-
function callApi(method) {
15-
return (...args)=>method(...args, {})
16-
;
17-
}
1811
concat([], []), concat([
1912
'hello'
2013
], [
@@ -52,22 +45,26 @@ concat([], []), concat([
5245
[
5346
'def'
5447
]
55-
]), curry((a, b, c, d)=>0
56-
), curry((a, b, c, d)=>0
57-
, 1), curry((a, b, c, d)=>0
58-
, 1, 'abc'), curry((a, b, c, d)=>0
59-
, 1, 'abc', !0), curry((a, b, c, d)=>0
60-
, 1, 'abc', !0, [
48+
]);
49+
const fn1 = (a, b, c, d)=>0
50+
;
51+
curry(fn1), curry(fn1, 1), curry(fn1, 1, 'abc'), curry(fn1, 1, 'abc', !0), curry(fn1, 1, 'abc', !0, [
6152
'x',
6253
'y'
63-
]), curry((x, b, ...args)=>0
64-
), curry((x, b, ...args)=>0
65-
, 1), curry((x, b, ...args)=>0
66-
, 1, !0), curry((x, b, ...args)=>0
67-
, 1, !0, 'abc', 'def'), curry((...args)=>0
68-
), curry((...args)=>0
69-
, 'abc', 'def'), curry((...args)=>0
70-
, ...sa), curry2(fn10, [
54+
]);
55+
const fn2 = (x, b, ...args)=>0
56+
;
57+
curry(fn2), curry(fn2, 1), curry(fn2, 1, !0), curry(fn2, 1, !0, 'abc', 'def');
58+
const fn3 = (...args)=>0
59+
;
60+
function curry2(f, t, u) {
61+
return f(...t, ...u);
62+
}
63+
function callApi(method) {
64+
return (...args)=>method(...args, {})
65+
;
66+
}
67+
curry(fn3), curry(fn3, 'abc', 'def'), curry(fn3, ...sa), curry2(fn10, [
7168
'hello',
7269
42
7370
], [
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Usage:
4+
#
5+
# From your clone of next.js, you can invoke this script like
6+
#
7+
# /absolute/path/to/this/script.sh examples/foo
8+
#
9+
# This script will
10+
#
11+
# - build native binary (`next-swc`)
12+
# - install dependnecies using `yarn``
13+
# - remove some dependencies (`next`, `react`, `react-dom`)
14+
# - yarn next build examples/foo
15+
# - yarn next start examples/foo
16+
set -eu
17+
18+
SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
19+
20+
dir="$1"
21+
nextJsDir="$(pwd)"
22+
23+
# Ensure that next-swc is up to date
24+
echo "----- ⚠️ Building next-swc"
25+
(cd ./packages/next-swc && yarn build-native)
26+
27+
# Install dependencies
28+
echo "----- ⚠️ Installing dependencies"
29+
if [ ! -d "$dir/node_modules" ]; then
30+
if test -f "$dir/yarn.lock"; then
31+
echo " Using yarn"
32+
# (cd $dir && yarn)
33+
else
34+
echo " Using yarn"
35+
# (cd $dir && npm ci)
36+
fi
37+
fi
38+
39+
40+
echo "----- ⚠️ Removing cache"
41+
(cd $dir && rm -rf .next)
42+
43+
echo "----- ⚠️ Replacing swc binary"
44+
mv packages/next-swc/native/*.node $dir/../node_modules/@next/swc-*/
45+
ls -alh $dir/../node_modules/@next/swc-*/
46+
47+
# Build and start
48+
echo "----- ⚠️ Building the app using next"
49+
(cd $dir && npx next build)
50+
(cd $dir && npx next start)

crates/swc_ecma_minifier/src/compress/optimize/inline.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,10 @@ where
157157
op: op!("!"), arg, ..
158158
}) => arg.is_lit(),
159159
Expr::This(..) => usage.is_fn_local,
160-
Expr::Arrow(arr) => is_arrow_simple_enough_for_copy(arr),
160+
Expr::Arrow(arr) => {
161+
!(usage.used_as_arg && usage.ref_count > 1)
162+
&& is_arrow_simple_enough_for_copy(arr)
163+
}
161164
_ => false,
162165
}
163166
{
@@ -251,7 +254,7 @@ where
251254
}
252255

253256
if usage.used_as_arg && !usage.is_fn_local {
254-
if let Expr::Fn(..) = &**init {
257+
if let Expr::Fn(..) | Expr::Arrow(..) = &**init {
255258
return;
256259
}
257260
}
@@ -466,7 +469,12 @@ where
466469

467470
if let Some(usage) = self.data.vars.get(&i.to_id()) {
468471
if usage.declared_as_catch_param {
469-
log_abort!("inline: [x] Declared as a catch parameter");
472+
log_abort!("inline: Declared as a catch parameter");
473+
return;
474+
}
475+
476+
if usage.used_as_arg && usage.ref_count > 1 {
477+
log_abort!("inline: Used as an arugment");
470478
return;
471479
}
472480

crates/swc_ecma_minifier/tests/TODO.txt

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,13 @@
11
asm/asm_mixed/input.js
22
collapse_vars/collapse_vars_do_while/input.js
3-
collapse_vars/collapse_vars_lvalues/input.js
4-
collapse_vars/collapse_vars_lvalues_drop_assign/input.js
53
collapse_vars/collapse_vars_misc1/input.js
6-
collapse_vars/collapse_vars_short_circuited_conditions/input.js
7-
collapse_vars/collapse_vars_side_effects_2/input.js
84
collapse_vars/issue_2497/input.js
9-
conditionals/ifs_5/input.js
105
drop_unused/keep_assign/input.js
116
drop_unused/reassign_const/input.js
127
drop_unused/var_catch_toplevel/input.js
138
evaluate/issue_2535_1/input.js
149
h 10000 armony/array_literal_with_spread_4a/input.js
15-
harmony/default_assign/input.js
16-
if_return/if_var_return/input.js
1710
inline/dont_inline_funcs_into_default_param_2/input.js
18-
inline/inline_into_scope_conflict/input.js
19-
issue_1034/non_hoisted_function_after_return_2a/input.js
20-
issue_1034/non_hoisted_function_after_return_2b/input.js
2111
issue_1052/defun_else_if_return/input.js
2212
issue_1052/defun_if_return/input.js
2313
issue_281/inner_var_for_in_1/input.js

crates/swc_ecma_minifier/tests/golden.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,7 @@ expression/pow_with_parentheses/input.js
532532
expression/pow_with_unary_between_brackets/input.js
533533
functions/avoid_generating_duplicate_functions_compared_together/input.js
534534
functions/avoid_generating_duplicate_functions_compared_together_2/input.js
535+
functions/avoid_generating_duplicate_functions_compared_together_3/input.js
535536
functions/avoid_generating_duplicate_functions_compared_together_4/input.js
536537
functions/deduplicate_parenthesis/input.js
537538
functions/drop_lone_use_strict/input.js

crates/swc_ecma_minifier/tests/postponed.txt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,15 @@ collapse_vars/collapse_vars_assignment/input.js
3939
collapse_vars/collapse_vars_constants/input.js
4040
collapse_vars/collapse_vars_do_while_drop_assign/input.js
4141
collapse_vars/collapse_vars_if/input.js
42+
collapse_vars/collapse_vars_lvalues/input.js
43+
collapse_vars/collapse_vars_lvalues_drop_assign/input.js
4244
collapse_vars/collapse_vars_object/input.js
4345
collapse_vars/collapse_vars_repeated/input.js
4446
collapse_vars/collapse_vars_self_reference/input.js
4547
collapse_vars/collapse_vars_short_circuit/input.js
48+
collapse_vars/collapse_vars_short_circuited_conditions/input.js
4649
collapse_vars/collapse_vars_side_effects_1/input.js
50+
collapse_vars/collapse_vars_side_effects_2/input.js
4751
collapse_vars/collapse_vars_switch/input.js
4852
collapse_vars/collapse_vars_unary/input.js
4953
collapse_vars/cond_branch_1/input.js
@@ -91,6 +95,7 @@ collapse_vars/var_defs/input.js
9195
collapse_vars/var_side_effects_2/input.js
9296
conditionals/equality_conditionals_false/input.js
9397
conditionals/hoist_decl/input.js
98+
conditionals/ifs_5/input.js
9499
conditionals/ifs_6/input.js
95100
conditionals/ifs_same_consequent/input.js
96101
conditionals/issue_1154/input.js
@@ -210,7 +215,6 @@ export/name_cache_import_star_as_name_from_module/input.js
210215
export/name_cache_mangle_export_default_class/input.js
211216
export/name_cache_mangle_export_default_function/input.js
212217
export/name_cache_mangle_local_import_and_export_aliases/input.js
213-
functions/avoid_generating_duplicate_functions_compared_together_3/input.js
214218
functions/duplicate_arg_var/input.js
215219
functions/empty_body/input.js
216220
functions/hoist_funs/input.js
@@ -280,6 +284,7 @@ harmony/array_spread_of_sequence/input.js
280284
harmony/class_name_can_be_mangled/input.js
281285
harmony/class_name_can_be_preserved_with_reserved/input.js
282286
harmony/classes_extending_classes_out_of_pure_iifes/input.js
287+
harmony/default_assign/input.js
283288
harmony/expansion/input.js
284289
harmony/fat_arrow_as_param/input.js
285290
harmony/import_statement_mangling/input.js
@@ -335,14 +340,18 @@ ie8/issue_2254_1/input.js
335340
ie8/issue_2254_2/input.js
336341
ie8/reduce_vars/input.js
337342
if_return/if_return_same_value/input.js
343+
if_return/if_var_return/input.js
338344
if_return/issue_2747/input.js
339345
if_return/issue_512/input.js
340346
inline/do_not_repeat_when_variable_larger_than_inlined_node/input.js
341347
inline/inline_annotation/input.js
348+
inline/inline_into_scope_conflict/input.js
342349
inline/inline_within_extends_1/input.js
343350
inline/inline_within_extends_2/input.js
344351
issue_1034/non_hoisted_function_after_return/input.js
352+
issue_1034/non_hoisted_function_after_return_2a/input.js
345353
issue_1034/non_hoisted_function_after_return_2a_strict/input.js
354+
issue_1034/non_hoisted_function_after_return_2b/input.js
346355
issue_1034/non_hoisted_function_after_return_2b_strict/input.js
347356
issue_1034/non_hoisted_function_after_return_strict/input.js
348357
issue_1052/deeply_nested/input.js

crates/swc_ecma_minifier/tests/terser_exec.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ use testing::assert_eq;
3434
#[testing::fixture(
3535
"tests/terser/compress/**/input.js",
3636
exclude(
37-
"functions/avoid_generating_duplicate_functions_compared_together_3/",
3837
// We don't care about ie8
3938
"ie8",
4039
// tests with infinite loops

0 commit comments

Comments
 (0)
0