aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2020-06-06 15:07:32 +0100
committerGitHub <noreply@github.com>2020-06-06 15:07:32 +0100
commit02e889e44996e9215fbbb4997c635518334df1c4 (patch)
tree332dc83237c02f6b1fd862305c100f2ba97ea9a9
parent486ce00b8ea879f1bd05a07033b6098cbde6facf (diff)
downloadtracifyjs-02e889e44996e9215fbbb4997c635518334df1c4.tar.gz
tracifyjs-02e889e44996e9215fbbb4997c635518334df1c4.zip
improve fix for #3958 (#3960)
-rw-r--r--lib/compress.js74
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,