eliminate invalid state caching in collapse_vars (#2502)

fixes #2497
This commit is contained in:
Alex Lam S.L
2017-11-24 04:12:37 +08:00
committed by GitHub
parent 30cfea2e7a
commit 8987780db6
2 changed files with 52 additions and 12 deletions

View File

@@ -869,7 +869,7 @@ merge(Compressor.prototype, {
&& !(node instanceof AST_SymbolDeclaration) && !(node instanceof AST_SymbolDeclaration)
&& lhs.equivalent_to(node)) { && lhs.equivalent_to(node)) {
if (is_lhs(node, parent)) { if (is_lhs(node, parent)) {
if (candidate.multiple) replaced++; if (value_def) replaced++;
return node; return node;
} }
CHANGED = abort = true; CHANGED = abort = true;
@@ -884,7 +884,7 @@ merge(Compressor.prototype, {
return make_node(AST_UnaryPrefix, candidate, candidate); return make_node(AST_UnaryPrefix, candidate, candidate);
} }
if (candidate instanceof AST_VarDef) { if (candidate instanceof AST_VarDef) {
if (candidate.multiple) { if (value_def) {
abort = false; abort = false;
return node; return node;
} }
@@ -958,12 +958,13 @@ merge(Compressor.prototype, {
extract_candidates(statements[stat_index]); extract_candidates(statements[stat_index]);
while (candidates.length > 0) { while (candidates.length > 0) {
var candidate = candidates.pop(); var candidate = candidates.pop();
var value_def = null;
var lhs = get_lhs(candidate); var lhs = get_lhs(candidate);
if (!lhs || is_lhs_read_only(lhs) || lhs.has_side_effects(compressor)) continue; if (!lhs || is_lhs_read_only(lhs) || lhs.has_side_effects(compressor)) continue;
// Locate symbols which may execute code outside of scanning range // Locate symbols which may execute code outside of scanning range
var lvalues = get_lvalues(candidate); var lvalues = get_lvalues(candidate);
if (lhs instanceof AST_SymbolRef) lvalues[lhs.name] = false; if (lhs instanceof AST_SymbolRef) lvalues[lhs.name] = false;
var replace_all = candidate.multiple; var replace_all = value_def;
if (!replace_all && lhs instanceof AST_SymbolRef) { if (!replace_all && lhs instanceof AST_SymbolRef) {
var def = lhs.definition(); var def = lhs.definition();
replace_all = def.references.length - def.replaced == 1; replace_all = def.references.length - def.replaced == 1;
@@ -980,13 +981,12 @@ merge(Compressor.prototype, {
for (var i = stat_index; !abort && i < statements.length; i++) { for (var i = stat_index; !abort && i < statements.length; i++) {
statements[i].transform(scanner); statements[i].transform(scanner);
} }
if (candidate.multiple) { if (value_def) {
var def = candidate.name.definition(); var def = candidate.name.definition();
if (abort && def.references.length - def.replaced > replaced) replaced = false; if (abort && def.references.length - def.replaced > replaced) replaced = false;
else { else {
abort = false; abort = false;
hit = candidate.name instanceof AST_SymbolFunarg; hit = candidate.name instanceof AST_SymbolFunarg;
var value_def = candidate.value.definition();
for (var i = stat_index; !abort && i < statements.length; i++) { for (var i = stat_index; !abort && i < statements.length; i++) {
statements[i].transform(multi_replacer); statements[i].transform(multi_replacer);
} }
@@ -1061,13 +1061,13 @@ merge(Compressor.prototype, {
} }
} }
function mangleable_var(expr) { function mangleable_var(var_def) {
var value = expr.value; var value = var_def.value;
if (!(value instanceof AST_SymbolRef)) return false; if (!(value instanceof AST_SymbolRef)) return;
if (value.name == "arguments") return false; if (value.name == "arguments") return;
if (value.definition().undeclared) return false; var def = value.definition();
expr.multiple = true; if (def.undeclared) return;
return true; return value_def = def;
} }
function get_lhs(expr) { function get_lhs(expr) {

View File

@@ -3578,3 +3578,43 @@ issue_2436_14: {
} }
expect_stdout: true expect_stdout: true
} }
issue_2497: {
options = {
collapse_vars: true,
unused: true,
}
input: {
function sample() {
if (true) {
for (var i = 0; i < 1; ++i) {
for (var k = 0; k < 1; ++k) {
var value = 1;
var x = value;
value = x ? x + 1 : 0;
}
}
} else {
for (var i = 0; i < 1; ++i) {
for (var k = 0; k < 1; ++k) {
var value = 1;
}
}
}
}
}
expect: {
function sample() {
if (true)
for (i = 0; i < 1; ++i)
for (k = 0; k < 1; ++k) {
value = 1;
value = value ? value + 1 : 0;
}
else
for (var i = 0; i < 1; ++i)
for (var k = 0; k < 1; ++k)
var value=1;
}
}
}