fix switch branch elimination (#1752)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sat, 1 Apr 2017 09:19:57 +0000 (17:19 +0800)
committerGitHub <noreply@github.com>
Sat, 1 Apr 2017 09:19:57 +0000 (17:19 +0800)
Merge unreachable case body with previous fallthrough case

fixes #1750

lib/compress.js
test/compress/issue-1750.js [new file with mode: 0644]

index 1d9cd40..fc11840 100644 (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 = [];
-                }
-                body.push(branch);
-                fallthrough = false;
-            } else {
-                body.push(branch);
-                fallthrough = true;
+                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);
         }
-        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){
diff --git a/test/compress/issue-1750.js b/test/compress/issue-1750.js
new file mode 100644 (file)
index 0000000..53a78e6
--- /dev/null
@@ -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"
+}