fix corner cases in collapse_vars & hoist_vars (#5412)

fixes #5411
This commit is contained in:
Alex Lam S.L
2022-04-06 21:12:03 +01:00
committed by GitHub
parent 998c9792da
commit 21bd4c4a9d
2 changed files with 105 additions and 15 deletions

View File

@@ -2059,13 +2059,17 @@ Compressor.prototype.compress = function(node) {
if (is_lhs(node, parent)) {
if (value_def && !hit_rhs) assign_used = true;
return node;
} else if (value_def) {
}
if (!hit_rhs && verify_ref && node.fixed !== lhs.fixed) {
abort = true;
return node;
}
if (value_def) {
if (stop_if_hit && assign_pos == 0) assign_pos = remaining - replaced;
if (!hit_rhs) replaced++;
return node;
} else {
replaced++;
}
replaced++;
changed = abort = true;
AST_Node.info("Collapsing {node} [{file}:{line},{col}]", {
node: node,
@@ -2240,6 +2244,7 @@ Compressor.prototype.compress = function(node) {
var candidate = hit_stack[hit_stack.length - 1];
var assign_pos = -1;
var assign_used = false;
var verify_ref = false;
var remaining;
var value_def = null;
var stop_after = null;
@@ -2958,6 +2963,7 @@ Compressor.prototype.compress = function(node) {
if (matches < remaining) {
remaining = matches;
assign_pos = 0;
verify_ref = true;
}
}
if (expr.operator == "=") mangleable_var(expr.right);
@@ -3266,9 +3272,13 @@ Compressor.prototype.compress = function(node) {
}
var def = lhs.definition();
if (def.references.length - def.replaced == referenced) return true;
return def.fixed && lhs.fixed && def.references.filter(function(ref) {
if (!def.fixed) return false;
if (!lhs.fixed) return false;
if (def.references.filter(function(ref) {
return ref.fixed === lhs.fixed;
}).length == referenced;
}).length != referenced) return false;
verify_ref = true;
return true;
}
function symbol_in_lvalues(sym, parent) {
@@ -7843,7 +7853,7 @@ Compressor.prototype.compress = function(node) {
var consts = new Dictionary();
var dirs = [];
var hoisted = [];
var vars = new Dictionary(), vars_found = 0;
var vars = new Dictionary();
var tt = new TreeTransformer(function(node, descend, in_list) {
if (node === self) return;
if (node instanceof AST_Directive) {
@@ -7871,7 +7881,6 @@ Compressor.prototype.compress = function(node) {
})) return node;
node.definitions.forEach(function(defn) {
vars.set(defn.name.name, defn);
++vars_found;
});
var seq = node.to_assignments();
if (p instanceof AST_ForEnumeration && p.init === node) {
@@ -7890,7 +7899,7 @@ Compressor.prototype.compress = function(node) {
}
});
self.transform(tt);
if (vars_found > 0) {
if (vars.size() > 0) {
// collect only vars which don't show up in self's arguments list
var defns = [];
if (self instanceof AST_Lambda) self.each_argname(function(argname) {
@@ -9658,8 +9667,16 @@ Compressor.prototype.compress = function(node) {
fixed.escaped = def.escaped;
name.fixed = fixed;
def.references.forEach(function(ref) {
var assigns = ref.fixed && ref.fixed.assigns;
if (assigns && assigns[0] === defn) assigns[0] = assign;
if (!ref.fixed) return;
var assigns = ref.fixed.assigns;
if (!assigns) return;
if (assigns[0] !== defn) return;
if (assigns.length > 1 || ref.fixed.to_binary || ref.fixed.to_prefix) {
assigns[0] = assign;
} else {
ref.fixed = fixed;
if (def.fixed === ref.fixed) def.fixed = fixed;
}
});
def.references.push(name);
}

View File

@@ -224,8 +224,7 @@ issue_4489: {
console.log(k);
}
expect: {
!(A = 0);
for (var k in true);
for (var k in !(A = 0));
console.log(k);
}
expect_stdout: "undefined"
@@ -407,9 +406,9 @@ issue_4893_2: {
expect: {
try{
(function() {
var b;
b = null;
b.p += 42;
var a;
a = null;
a.p += 42;
})();
} catch (e) {
console.log("PASS");
@@ -530,3 +529,77 @@ issue_5378: {
"undefined",
]
}
issue_5411_1: {
options = {
collapse_vars: true,
dead_code: true,
hoist_vars: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
}
input: {
var a = "PASS";
b++;
b = a;
var b = b, c = c && c[b];
console.log(b);
}
expect: {
var b, c, a = "PASS";
b++;
b = a;
c = c && c[b];
console.log(b);
}
expect_stdout: "PASS"
}
issue_5411_2: {
options = {
collapse_vars: true,
dead_code: true,
evaluate: true,
hoist_vars: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a = "PASS";
b++;
b = a;
var b = b, c = c && c[b];
console.log(b);
}
expect: {
var b, c;
b++;
b = "PASS",
c = c && c[b];
console.log(b);
}
expect_stdout: "PASS"
}
issue_5411_3: {
options = {
collapse_vars: true,
hoist_vars: true,
reduce_vars: true,
toplevel: true,
}
input: {
var a = console;
a++;
var a = A = a;
console.log(A);
}
expect: {
var a = console;
a = A = ++a;
console.log(A);
}
expect_stdout: "NaN"
}