diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2017-11-08 03:28:46 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-08 03:28:46 +0800 |
commit | 4c0b0177b6fa556c31f0099c6d52a4ad4f670ba3 (patch) | |
tree | 708f43dcb264d0cab353bbeb2144bcbfb667f20d /lib/compress.js | |
parent | 38bfb73f0643d73d429d7a79667f6b8fa3fd6fc5 (diff) | |
download | tracifyjs-4c0b0177b6fa556c31f0099c6d52a4ad4f670ba3.tar.gz tracifyjs-4c0b0177b6fa556c31f0099c6d52a4ad4f670ba3.zip |
preserve function identity in `reduce_vars` (#2451)
fixes #2450
Diffstat (limited to 'lib/compress.js')
-rw-r--r-- | lib/compress.js | 45 |
1 files changed, 27 insertions, 18 deletions
diff --git a/lib/compress.js b/lib/compress.js index 274ab604..6354197d 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -324,9 +324,8 @@ merge(Compressor.prototype, { || value.is_constant_expression(node.scope); } else { d.single_use = d.scope === node.scope - && loop_ids[d.id] === in_loop && value.is_constant_expression(); - } + } } else { d.single_use = false; } @@ -384,6 +383,7 @@ merge(Compressor.prototype, { d.fixed = false; } else { d.fixed = node; + loop_ids[d.id] = in_loop; mark(d, true); if (ref_once(d)) { d.single_use = d.scope === d.references[0].scope @@ -577,7 +577,11 @@ merge(Compressor.prototype, { } function ref_once(def) { - return unused && !def.scope.uses_eval && !def.scope.uses_with && def.references.length == 1; + return unused + && !def.scope.uses_eval + && !def.scope.uses_with + && def.references.length == 1 + && loop_ids[def.id] === in_loop; } function is_immutable(value) { @@ -623,7 +627,8 @@ merge(Compressor.prototype, { function mark_escaped(d, node, value, level) { var parent = tw.parent(level); - if (value instanceof AST_Constant || value instanceof AST_Function) return; + if (value instanceof AST_Constant) return; + if (level > 0 && value instanceof AST_Function) return; if (parent instanceof AST_Assign && parent.operator == "=" && node === parent.right || parent instanceof AST_Call && node !== parent.expression || parent instanceof AST_Return && node === parent.value && node.scope !== d.scope @@ -4216,6 +4221,17 @@ merge(Compressor.prototype, { return self; }); + function recursive_ref(compressor, def) { + var node; + for (var i = 0; node = compressor.parent(i); i++) { + if (node instanceof AST_Lambda) { + var name = node.name; + if (name && name.definition() === def) break; + } + } + return node; + } + OPT(AST_SymbolRef, function(self, compressor){ var def = self.resolve_defines(compressor); if (def) { @@ -4241,20 +4257,13 @@ merge(Compressor.prototype, { if (fixed instanceof AST_Defun) { d.fixed = fixed = make_node(AST_Function, fixed, fixed); } - if (fixed && d.single_use) { - var recurse; - if (fixed instanceof AST_Function) { - for (var i = 0; recurse = compressor.parent(i); i++) { - if (recurse instanceof AST_Lambda) { - var name = recurse.name; - if (name && name.definition() === d) break; - } - } - } - if (!recurse) { - var value = fixed.optimize(compressor); - return value === fixed ? fixed.clone(true) : value; - } + if (fixed + && d.single_use + && !(fixed instanceof AST_Function + && (d.escaped && d.scope !== self.scope + || recursive_ref(compressor, d)))) { + var value = fixed.optimize(compressor); + return value === fixed ? fixed.clone(true) : value; } if (fixed && d.should_replace === undefined) { var init; |