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 default_branch;
var exact_match;
var fallthrough;
for (var i = 0, len = self.body.length; i < len && !exact_match; i++) {
branch = self.body[i];
if (branch instanceof AST_Default) {
if (!default_branch) default_branch = branch;
else if (!fallthrough) {
extract_declarations_from_unreachable_code(compressor, branch, decl);
continue;
if (!default_branch) {
default_branch = branch;
} else {
eliminate_branch(branch);
}
} else if (value !== self.expression) {
var exp = branch.expression.evaluate(compressor);
if (exp === value) {
exact_match = branch;
if (default_branch) {
body.splice(body.indexOf(default_branch), 1);
extract_declarations_from_unreachable_code(compressor, default_branch, decl);
var default_index = body.indexOf(default_branch);
body.splice(default_index, 1);
eliminate_branch(default_branch, body[default_index - 1]);
default_branch = null;
}
} else if (exp !== branch.expression && !fallthrough) {
extract_declarations_from_unreachable_code(compressor, branch, decl);
} else if (exp !== branch.expression) {
eliminate_branch(branch);
continue;
}
}
if (aborts(branch)) {
if (body.length > 0 && !fallthrough) {
var prev = body[body.length - 1];
if (prev.body.length == branch.body.length
&& make_node(AST_BlockStatement, prev, prev).equivalent_to(make_node(AST_BlockStatement, branch, branch)))
prev.body = [];
var prev = body[body.length - 1];
if (aborts(prev) && prev.body.length == branch.body.length
&& make_node(AST_BlockStatement, prev, prev).equivalent_to(make_node(AST_BlockStatement, branch, branch))) {
prev.body = [];
}
body.push(branch);
fallthrough = false;
} else {
body.push(branch);
fallthrough = true;
}
body.push(branch);
}
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);
while (i < len) eliminate_branch(self.body[i++]);
if (body.length > 0) {
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);
}
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){