fix corner cases in reduce_vars (#5717)

fixes #5716
This commit is contained in:
Alex Lam S.L
2022-10-19 18:22:19 +03:00
committed by GitHub
parent 8319badea8
commit 19c471c16a
2 changed files with 178 additions and 41 deletions

View File

@@ -501,6 +501,23 @@ Compressor.prototype.compress = function(node) {
if (parent instanceof AST_VarDef) return parent.value === node;
}
function make_ref(ref, fixed) {
var node = make_node(AST_SymbolRef, ref);
node.fixed = fixed || make_node(AST_Undefined, ref);
return node;
}
function replace_ref(resolve, fixed) {
return function(node) {
var ref = resolve(node);
var node = make_ref(ref, fixed);
var def = ref.definition();
def.references.push(node);
def.replaced++;
return node;
};
}
var RE_POSITIVE_INTEGER = /^(0|[1-9][0-9]*)$/;
(function(def) {
def(AST_Node, noop);
@@ -705,22 +722,6 @@ Compressor.prototype.compress = function(node) {
});
}
function make_ref(ref, fixed) {
var node = make_node(AST_SymbolRef, ref);
node.fixed = fixed || make_node(AST_Undefined, ref);
return node;
}
function replace_ref(ref, fixed) {
return function() {
var node = make_ref(ref, fixed);
var def = ref.definition();
def.references.push(node);
def.replaced++;
return node;
};
}
function ref_once(compressor, def) {
return compressor.option("unused")
&& !def.scope.pinned()
@@ -1021,7 +1022,9 @@ Compressor.prototype.compress = function(node) {
};
left.fixed.assigns = !fixed || !fixed.assigns ? [ ld.orig[0] ] : fixed.assigns.slice();
left.fixed.assigns.push(node);
left.fixed.to_binary = replace_ref(left, fixed);
left.fixed.to_binary = replace_ref(function(node) {
return node.left;
}, fixed);
} else {
left.walk(tw);
ld.fixed = false;
@@ -1529,7 +1532,9 @@ Compressor.prototype.compress = function(node) {
});
};
exp.fixed.assigns = fixed && fixed.assigns;
exp.fixed.to_prefix = replace_ref(exp, d.fixed);
exp.fixed.to_prefix = replace_ref(function(node) {
return node.expression;
}, d.fixed);
}
} else {
exp.walk(tw);
@@ -2156,7 +2161,7 @@ Compressor.prototype.compress = function(node) {
abort = true;
folded = make_node(AST_Binary, candidate, {
operator: compound,
left: lhs.fixed && lhs.definition().fixed ? lhs.fixed.to_binary() : lhs,
left: lhs.fixed && lhs.definition().fixed ? lhs.fixed.to_binary(candidate) : lhs,
right: rvalue,
});
}
@@ -2220,7 +2225,7 @@ Compressor.prototype.compress = function(node) {
}
if (candidate instanceof AST_UnaryPostfix) return make_node(AST_UnaryPrefix, candidate, {
operator: candidate.operator,
expression: lhs.fixed && lhs.definition().fixed ? lhs.fixed.to_prefix() : lhs,
expression: lhs.fixed && lhs.definition().fixed ? lhs.fixed.to_prefix(candidate) : lhs,
});
if (candidate instanceof AST_UnaryPrefix) {
clear_write_only(candidate);
@@ -12780,34 +12785,19 @@ Compressor.prototype.compress = function(node) {
}
if (compressor.option("assignments")) {
if (self.operator == "=" && self.left instanceof AST_SymbolRef && self.right instanceof AST_Binary) {
var ref;
// x = expr1 OP expr2
if ((ref = self.right.left) instanceof AST_SymbolRef
&& ref.name == self.left.name
if (self.right.left instanceof AST_SymbolRef
&& self.right.left.name == self.left.name
&& ASSIGN_OPS[self.right.operator]) {
// x = x - 2 ---> x -= 2
if (self.left.fixed) self.left.fixed.to_binary = function() {
return ref;
};
return make_node(AST_Assign, self, {
operator: self.right.operator + "=",
left: self.left,
right: self.right.right,
});
return make_compound(self.right.right);
}
if ((ref = self.right.right) instanceof AST_SymbolRef
&& ref.name == self.left.name
if (self.right.right instanceof AST_SymbolRef
&& self.right.right.name == self.left.name
&& ASSIGN_OPS_COMMUTATIVE[self.right.operator]
&& !self.right.left.has_side_effects(compressor)) {
// x = 2 & x ---> x &= 2
if (self.left.fixed) self.left.fixed.to_binary = function() {
return ref;
};
return make_node(AST_Assign, self, {
operator: self.right.operator + "=",
left: self.left,
right: self.right.left,
});
return make_compound(self.right.left);
}
}
if ((self.operator == "-=" || self.operator == "+="
@@ -12870,6 +12860,18 @@ Compressor.prototype.compress = function(node) {
return find_try(compressor, level, node, scope, may_throw, sync);
}
function make_compound(rhs) {
var fixed = self.left.fixed;
if (fixed) fixed.to_binary = replace_ref(function(node) {
return node.left;
}, fixed);
return make_node(AST_Assign, self, {
operator: self.right.operator + "=",
left: self.left,
right: rhs,
});
}
function strip_assignment(def) {
if (def) def.fixed = false;
return (self.operator != "=" ? make_node(AST_Binary, self, {