8026008: Constant folding removes var statement

Reviewed-by: sundar, jlaskey
This commit is contained in:
Hannes Wallnöfer 2013-10-09 14:50:39 +02:00
parent a7261c57e0
commit 3ef5f027ce
3 changed files with 87 additions and 4 deletions

View File

@ -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.LexicalContext;
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 @@ final class FoldConstants extends NodeVisitor<LexicalContext> {
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 @@ final class FoldConstants extends NodeVisitor<LexicalContext> {
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);

View File

@ -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
}

View File

@ -0,0 +1,3 @@
undefined undefined
undefined undefined
undefined undefined