diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2020-06-06 15:07:32 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-06 15:07:32 +0100 |
commit | 02e889e44996e9215fbbb4997c635518334df1c4 (patch) | |
tree | 332dc83237c02f6b1fd862305c100f2ba97ea9a9 | |
parent | 486ce00b8ea879f1bd05a07033b6098cbde6facf (diff) | |
download | tracifyjs-02e889e44996e9215fbbb4997c635518334df1c4.tar.gz tracifyjs-02e889e44996e9215fbbb4997c635518334df1c4.zip |
improve fix for #3958 (#3960)
-rw-r--r-- | lib/compress.js | 74 |
1 files changed, 32 insertions, 42 deletions
diff --git a/lib/compress.js b/lib/compress.js index f71d9568..6aa81a52 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -352,23 +352,6 @@ merge(Compressor.prototype, { return orig.length == 1 && orig[0] instanceof AST_SymbolFunarg; } - function is_content_constant(ref, depth) { - var escaped = ref.definition().escaped; - switch (escaped.length) { - case 0: - return true; - case 1: - var found = false; - escaped[0].walk(new TreeWalker(function(node) { - if (found) return true; - if (node === ref) return found = true; - })); - return found; - default: - return depth <= escaped.depth; - } - } - (function(def) { def(AST_Node, noop); @@ -512,16 +495,10 @@ merge(Compressor.prototype, { }); } - function to_value(def, sym, fixed) { - if (fixed == null) { - fixed = make_node(AST_Undefined, sym); - } else if (typeof fixed == "function") { - fixed = fixed(); - } - if (fixed instanceof AST_Array || fixed instanceof AST_Object) { - if (!is_content_constant(sym)) return false; - } - return fixed; + function make_ref(ref, fixed) { + var node = make_node(AST_SymbolRef, ref, ref); + node.fixed = fixed || make_node(AST_Undefined, ref); + return node; } function ref_once(compressor, def) { @@ -618,10 +595,9 @@ merge(Compressor.prototype, { }; } else { sym.fixed = d.fixed = function() { - var value = to_value(d, sym, fixed); - return value && make_node(AST_Binary, node, { + return make_node(AST_Binary, node, { operator: node.operator.slice(0, -1), - left: value, + left: make_ref(sym, fixed), right: node.right }); }; @@ -900,12 +876,11 @@ merge(Compressor.prototype, { push_ref(d, exp); mark(tw, d); d.fixed = function() { - var value = to_value(d, exp, fixed); - return value && make_node(AST_Binary, node, { + return make_node(AST_Binary, node, { operator: node.operator.slice(0, -1), left: make_node(AST_UnaryPrefix, node, { operator: "+", - expression: value + expression: make_ref(exp, fixed) }), right: make_node(AST_Number, node, { value: 1 @@ -918,10 +893,9 @@ merge(Compressor.prototype, { exp.fixed = d.fixed; } else { exp.fixed = function() { - var value = to_value(d, exp, fixed); - return value && make_node(AST_UnaryPrefix, node, { + return make_node(AST_UnaryPrefix, node, { operator: "+", - expression: value + expression: make_ref(exp, fixed) }); }; exp.fixed.assigns = fixed && fixed.assigns; @@ -3416,7 +3390,8 @@ merge(Compressor.prototype, { && e.fixed_value() instanceof AST_Lambda)) { return typeof function(){}; } - if (!non_converting_unary[op]) depth++; + var def = e instanceof AST_SymbolRef && e.definition(); + if (!non_converting_unary[op] && !(def && def.fixed)) depth++; var v = e._eval(compressor, ignore_side_effects, cached, depth); if (v === e) { if (ignore_side_effects && op == "void") return; @@ -3435,9 +3410,8 @@ merge(Compressor.prototype, { case "+": return +v; case "++": case "--": - if (!(e instanceof AST_SymbolRef)) return this; + if (!def) return this; if (!ignore_side_effects) { - var def = e.definition(); if (def.undeclared) return this; if (def.last_ref !== e) return this; } @@ -3460,7 +3434,8 @@ merge(Compressor.prototype, { if (def.last_ref !== e) return this; } } - var v = e._eval(compressor, ignore_side_effects, cached, depth + 1); + if (!(e instanceof AST_SymbolRef && e.definition().fixed)) depth++; + var v = e._eval(compressor, ignore_side_effects, cached, depth); if (v === e) return this; modified(e); return +v; @@ -3522,6 +3497,22 @@ merge(Compressor.prototype, { var value = node._eval(compressor, ignore_side_effects, cached, depth); return value === node ? this : value; }); + function verify_escaped(ref, depth) { + var escaped = ref.definition().escaped; + switch (escaped.length) { + case 0: + return true; + case 1: + var found = false; + escaped[0].walk(new TreeWalker(function(node) { + if (found) return true; + if (node === ref) return found = true; + })); + return found; + default: + return depth <= escaped.depth; + } + } def(AST_SymbolRef, function(compressor, ignore_side_effects, cached, depth) { var fixed = this.fixed_value(); if (!fixed) return this; @@ -3538,8 +3529,7 @@ merge(Compressor.prototype, { }; cached.push(fixed); } - if (value && typeof value == "object" && !is_content_constant(this, depth)) return this; - return value; + return value && typeof value == "object" && !verify_escaped(this, depth) ? this : value; }); var global_objs = { Array: Array, |