fix switch branch elimination (#1752)

Merge unreachable case body with previous fallthrough case

fixes #1750
This commit is contained in:
Alex Lam S.L
2017-04-01 17:19:57 +08:00
committed by GitHub
parent 87f6e1b091
commit ee3fe0f4cd
2 changed files with 49 additions and 25 deletions

View File

@@ -2537,49 +2537,39 @@ merge(Compressor.prototype, {
var body = []; var body = [];
var default_branch; var default_branch;
var exact_match; var exact_match;
var fallthrough;
for (var i = 0, len = self.body.length; i < len && !exact_match; i++) { for (var i = 0, len = self.body.length; i < len && !exact_match; i++) {
branch = self.body[i]; branch = self.body[i];
if (branch instanceof AST_Default) { if (branch instanceof AST_Default) {
if (!default_branch) default_branch = branch; if (!default_branch) {
else if (!fallthrough) { default_branch = branch;
extract_declarations_from_unreachable_code(compressor, branch, decl); } else {
continue; eliminate_branch(branch);
} }
} else if (value !== self.expression) { } else if (value !== self.expression) {
var exp = branch.expression.evaluate(compressor); var exp = branch.expression.evaluate(compressor);
if (exp === value) { if (exp === value) {
exact_match = branch; exact_match = branch;
if (default_branch) { if (default_branch) {
body.splice(body.indexOf(default_branch), 1); var default_index = body.indexOf(default_branch);
extract_declarations_from_unreachable_code(compressor, default_branch, decl); body.splice(default_index, 1);
eliminate_branch(default_branch, body[default_index - 1]);
default_branch = null; default_branch = null;
} }
} else if (exp !== branch.expression && !fallthrough) { } else if (exp !== branch.expression) {
extract_declarations_from_unreachable_code(compressor, branch, decl); eliminate_branch(branch);
continue; continue;
} }
} }
if (aborts(branch)) { if (aborts(branch)) {
if (body.length > 0 && !fallthrough) {
var prev = body[body.length - 1]; var prev = body[body.length - 1];
if (prev.body.length == branch.body.length if (aborts(prev) && prev.body.length == branch.body.length
&& make_node(AST_BlockStatement, prev, prev).equivalent_to(make_node(AST_BlockStatement, branch, branch))) && make_node(AST_BlockStatement, prev, prev).equivalent_to(make_node(AST_BlockStatement, branch, branch))) {
prev.body = []; prev.body = [];
} }
}
body.push(branch); body.push(branch);
fallthrough = false;
} else {
body.push(branch);
fallthrough = true;
} }
} while (i < len) eliminate_branch(self.body[i++]);
for (; i < len && fallthrough; i++) {
branch = self.body[i];
exact_match.body = exact_match.body.concat(branch.body);
fallthrough = !aborts(exact_match);
}
while (i < len) extract_declarations_from_unreachable_code(compressor, self.body[i++], decl);
if (body.length > 0) { if (body.length > 0) {
body[0].body = decl.concat(body[0].body); body[0].body = decl.concat(body[0].body);
} }
@@ -2612,6 +2602,15 @@ merge(Compressor.prototype, {
if (!has_break) return make_node(AST_BlockStatement, self, body[0]).optimize(compressor); if (!has_break) return make_node(AST_BlockStatement, self, body[0]).optimize(compressor);
} }
return self; return self;
function eliminate_branch(branch, prev) {
if (!prev) prev = body[body.length - 1];
if (prev && !aborts(prev)) {
prev.body = prev.body.concat(branch.body);
} else {
extract_declarations_from_unreachable_code(compressor, branch, decl);
}
}
}); });
OPT(AST_Try, function(self, compressor){ OPT(AST_Try, function(self, compressor){

View File

@@ -0,0 +1,25 @@
case_1: {
options = {
dead_code: true,
evaluate: true,
}
input: {
var a = 0, b = 1;
switch (true) {
case a, true:
default:
b = 2;
case true:
}
console.log(a, b);
}
expect: {
var a = 0, b = 1;
switch (true) {
case a, true:
b = 2;
}
console.log(a, b);
}
expect_stdout: "0 2"
}