improve fix for #3958 (#3960)

This commit is contained in:
Alex Lam S.L
2020-06-06 15:07:32 +01:00
committed by GitHub
parent 486ce00b8e
commit 02e889e449

View File

@@ -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,