From 67d0237f73c3147855983edde137cd95a2cb1749 Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Tue, 28 Mar 2017 03:59:13 +0800 Subject: [PATCH] fix tail trimming of switch blocks (#1707) now guarded under `dead_code` fixes #1705 --- lib/compress.js | 105 ++++++++++++++++++++-------------------- test/compress/switch.js | 66 +++++++++++++++++++++++++ 2 files changed, 118 insertions(+), 53 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index 1146f300..e2fde883 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -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; + 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; + } + } 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 (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 (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 (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); - } - 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); + 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; } - 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 diff --git a/test/compress/switch.js b/test/compress/switch.js index 9f9d3568..5c12449c 100644 --- a/test/compress/switch.js +++ b/test/compress/switch.js @@ -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 +} -- 2.34.1