diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2017-12-26 21:25:35 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-12-26 21:25:35 +0800 |
commit | 4832bc5d88e37ca35f1dd5f5d8ddd95cd8bbdd7d (patch) | |
tree | 925053e75bf5109861b7fdb54e30f0e5ae4b960f /lib/compress.js | |
parent | 7f342cb3e3abd3e39b18e62a2e9d6b8020d82773 (diff) | |
download | tracifyjs-4832bc5d88e37ca35f1dd5f5d8ddd95cd8bbdd7d.tar.gz tracifyjs-4832bc5d88e37ca35f1dd5f5d8ddd95cd8bbdd7d.zip |
replace single-use recursive functions (#2659)
fixes #2628
Diffstat (limited to 'lib/compress.js')
-rw-r--r-- | lib/compress.js | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/lib/compress.js b/lib/compress.js index bb355423..d890caf7 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -319,6 +319,7 @@ merge(Compressor.prototype, { } else { def.fixed = false; } + def.recursive_refs = 0; def.references = []; def.should_replace = undefined; def.single_use = undefined; @@ -369,7 +370,7 @@ merge(Compressor.prototype, { return compressor.option("unused") && !def.scope.uses_eval && !def.scope.uses_with - && def.references.length == 1 + && def.references.length - def.recursive_refs == 1 && tw.loop_ids[def.id] === tw.in_loop; } @@ -621,7 +622,9 @@ merge(Compressor.prototype, { d.fixed = false; } else if (d.fixed) { value = this.fixed_value(); - if (value && ref_once(tw, compressor, d)) { + if (value instanceof AST_Lambda && recursive_ref(tw, d)) { + d.recursive_refs++; + } else if (value && ref_once(tw, compressor, d)) { d.single_use = value instanceof AST_Lambda || d.scope === this.scope && value.is_constant_expression(); } else { @@ -4670,17 +4673,18 @@ merge(Compressor.prototype, { if (fixed instanceof AST_Defun) { d.fixed = fixed = make_node(AST_Function, fixed, fixed); } - if (d.single_use && fixed instanceof AST_Function) { + var single_use = d.single_use; + if (single_use && fixed instanceof AST_Function) { if (d.scope !== self.scope && (!compressor.option("reduce_funcs") || d.escaped == 1 || fixed.inlined)) { - d.single_use = false; + single_use = false; } else if (recursive_ref(compressor, d)) { - d.single_use = false; + single_use = false; } else if (d.scope !== self.scope || d.orig[0] instanceof AST_SymbolFunarg) { - d.single_use = fixed.is_constant_expression(self.scope); - if (d.single_use == "f") { + single_use = fixed.is_constant_expression(self.scope); + if (single_use == "f") { var scope = self.scope; do { if (scope instanceof AST_Defun || scope instanceof AST_Function) { @@ -4690,9 +4694,24 @@ merge(Compressor.prototype, { } } } - if (d.single_use && fixed) { - var value = fixed.optimize(compressor); - return value === fixed ? fixed.clone(true) : value; + if (single_use && fixed) { + var value; + if (d.recursive_refs > 0 && fixed.name instanceof AST_SymbolDefun) { + value = fixed.clone(true); + var defun_def = value.name.definition(); + value.name = make_node(AST_SymbolLambda, value.name, value.name); + value.name.scope = value; + var lambda_def = value.def_function(value.name); + value.walk(new TreeWalker(function(node) { + if (node instanceof AST_SymbolRef && node.definition() === defun_def) { + node.thedef = lambda_def; + } + })); + } else { + value = fixed.optimize(compressor); + if (value === fixed) value = fixed.clone(true); + } + return value; } if (fixed && d.should_replace === undefined) { var init; |