fix tail trimming of switch blocks (#1707)

now guarded under `dead_code`

fixes #1705
This commit is contained in:
Alex Lam S.L
2017-03-28 03:59:13 +08:00
committed by GitHub
parent 984a21704e
commit 67d0237f73
2 changed files with 118 additions and 53 deletions

View File

@@ -2509,74 +2509,73 @@ merge(Compressor.prototype, {
var expression = make_node_from_constant(value, self.expression).transform(compressor);
self.expression = best_of_expression(expression, self.expression);
}
if (compressor.option("dead_code")) {
var prev_block;
var decl = [];
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;
}
} 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);
}
} else if (exp !== branch.expression && !fallthrough) {
extract_declarations_from_unreachable_code(compressor, branch, decl);
continue;
}
if (!compressor.option("dead_code")) return self;
var prev_block;
var decl = [];
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 (aborts(branch)) {
var block = make_node(AST_BlockStatement, branch, branch).print_to_string();
if (!fallthrough && prev_block === block) body[body.length - 1].body = [];
body.push(branch);
prev_block = block;
fallthrough = false;
} else {
body.push(branch);
prev_block = null;
fallthrough = true;
} 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);
default_branch = null;
}
} else if (exp !== branch.expression && !fallthrough) {
extract_declarations_from_unreachable_code(compressor, branch, decl);
continue;
}
}
for (; i < len && fallthrough; i++) {
branch = self.body[i];
exact_match.body = exact_match.body.concat(branch.body);
fallthrough = !aborts(exact_match);
if (aborts(branch)) {
var block = make_node(AST_BlockStatement, branch, branch).print_to_string();
if (!fallthrough && prev_block === block) body[body.length - 1].body = [];
body.push(branch);
prev_block = block;
fallthrough = false;
} else {
body.push(branch);
prev_block = null;
fallthrough = true;
}
while (i < len) extract_declarations_from_unreachable_code(compressor, self.body[i++], decl);
if (body.length > 0) {
body[0].body = decl.concat(body[0].body);
}
self.body = body;
}
while (branch = self.body[self.body.length - 1]) {
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) {
body[0].body = decl.concat(body[0].body);
}
self.body = body;
while (branch = body[body.length - 1]) {
var stat = branch.body[branch.body.length - 1];
if (stat instanceof AST_Break && compressor.loopcontrol_target(stat.label) === self)
branch.body.pop();
if (branch.body.length
|| branch instanceof AST_Case
&& branch.expression.has_side_effects(compressor)) break;
self.body.pop();
if (branch.body.length || branch instanceof AST_Case
&& (default_branch || branch.expression.has_side_effects(compressor))) break;
if (body.pop() === default_branch) default_branch = null;
}
if (decl && self.body.length == 0) {
if (body.length == 0) {
return make_node(AST_BlockStatement, self, {
body: decl.concat(make_node(AST_SimpleStatement, self.expression, {
body: self.expression
}))
}).optimize(compressor);
}
if (body && body.length == 1 && (body[0] === exact_match || body[0] === default_branch)) {
if (body.length == 1 && (body[0] === exact_match || body[0] === default_branch)) {
var has_break = false;
var tw = new TreeWalker(function(node) {
if (has_break

View File

@@ -614,3 +614,69 @@ issue_1698: {
}
expect_stdout: "2"
}
issue_1705_1: {
options = {
dead_code: true,
}
input: {
var a = 0;
switch (a) {
default:
console.log("FAIL");
case 0:
break;
}
}
expect: {
var a = 0;
switch (a) {
default:
console.log("FAIL");
case 0:
}
}
expect_stdout: true
}
issue_1705_2: {
options = {
dead_code: true,
evaluate: true,
reduce_vars: true,
sequences: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a = 0;
switch (a) {
default:
console.log("FAIL");
case 0:
break;
}
}
expect: {
}
expect_stdout: true
}
issue_1705_3: {
options = {
dead_code: true,
}
input: {
switch (a) {
case 0:
break;
default:
break;
}
}
expect: {
a;
}
expect_stdout: true
}