8026008: Constant folding removes var statement
authorhannesw
Wed, 09 Oct 2013 14:50:39 +0200
changeset 20927 795730245d55
parent 20926 9c7625a91b68
child 20928 3ff39d5c8c08
8026008: Constant folding removes var statement Reviewed-by: sundar, jlaskey
nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java
nashorn/test/script/basic/JDK-8026008.js
nashorn/test/script/basic/JDK-8026008.js.EXPECTED
--- a/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java	Wed Oct 09 13:26:23 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java	Wed Oct 09 14:50:39 2013 +0200
@@ -25,6 +25,8 @@
 
 package jdk.nashorn.internal.codegen;
 
+import java.util.ArrayList;
+import java.util.List;
 import jdk.nashorn.internal.codegen.types.Type;
 import jdk.nashorn.internal.ir.BinaryNode;
 import jdk.nashorn.internal.ir.Block;
@@ -37,8 +39,10 @@
 import jdk.nashorn.internal.ir.LiteralNode;
 import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
 import jdk.nashorn.internal.ir.Node;
+import jdk.nashorn.internal.ir.Statement;
 import jdk.nashorn.internal.ir.TernaryNode;
 import jdk.nashorn.internal.ir.UnaryNode;
+import jdk.nashorn.internal.ir.VarNode;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
 import jdk.nashorn.internal.runtime.DebugLogger;
 import jdk.nashorn.internal.runtime.JSType;
@@ -89,11 +93,21 @@
     public Node leaveIfNode(final IfNode ifNode) {
         final Node test = ifNode.getTest();
         if (test instanceof LiteralNode.PrimitiveLiteralNode) {
-            final Block shortCut = ((LiteralNode.PrimitiveLiteralNode<?>)test).isTrue() ? ifNode.getPass() : ifNode.getFail();
-            if (shortCut != null) {
-                return new BlockStatement(ifNode.getLineNumber(), shortCut);
+            final boolean isTrue = ((LiteralNode.PrimitiveLiteralNode<?>)test).isTrue();
+            final Block executed = isTrue ? ifNode.getPass() : ifNode.getFail();
+            final Block dropped  = isTrue ? ifNode.getFail() : ifNode.getPass();
+            final List<Statement> statements = new ArrayList<>();
+
+            if (executed != null) {
+                statements.addAll(executed.getStatements()); // Get statements form executed branch
             }
-            return new EmptyNode(ifNode);
+            if (dropped != null) {
+                extractVarNodes(dropped, statements); // Get var-nodes from non-executed branch
+            }
+            if (statements.isEmpty()) {
+                return new EmptyNode(ifNode);
+            }
+            return BlockStatement.createReplacement(ifNode, ifNode.getFinish(), statements);
         }
         return ifNode;
     }
@@ -131,6 +145,17 @@
         protected abstract LiteralNode<?> eval();
     }
 
+    private static void extractVarNodes(final Block block, final List<Statement> statements) {
+        final LexicalContext lc = new LexicalContext();
+        block.accept(lc, new NodeVisitor<LexicalContext>(lc) {
+            @Override
+            public boolean enterVarNode(VarNode varNode) {
+                statements.add(varNode.setInit(null));
+                return false;
+            }
+        });
+    }
+
     private static class UnaryNodeConstantEvaluator extends ConstantEvaluator<UnaryNode> {
         UnaryNodeConstantEvaluator(final UnaryNode parent) {
             super(parent);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8026008.js	Wed Oct 09 14:50:39 2013 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8026008: Constant folding removes var statement
+ *
+ * @test
+ * @run
+ */
+
+if (false) {
+    var x1 = 10;
+    if (false) {
+        var x2;
+    }
+} else {
+   print(x1, x2);
+}
+
+if (undefined) {
+    var z1;
+    if (null) {
+        var z2;
+    }
+}
+
+print(z1, z2);
+
+if (1) {
+    print(y1, y2);
+} else if (0) {
+    var y1 = 1;
+} else {
+    var y2 = 2
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8026008.js.EXPECTED	Wed Oct 09 14:50:39 2013 +0200
@@ -0,0 +1,3 @@
+undefined undefined
+undefined undefined
+undefined undefined