Mon, 18 Nov 2013 16:35:39 +0100
8028434: Line number nodes were off for while nodes and do while nodes - the line number of a loop node should be treated as the location of the test expression
Reviewed-by: jlaskey, sundar
1.1 --- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java Sat Nov 16 00:23:46 2013 +0100 1.2 +++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java Mon Nov 18 16:35:39 2013 +0100 1.3 @@ -2186,15 +2186,14 @@ 1.4 1.5 @Override 1.6 public boolean enterWhileNode(final WhileNode whileNode) { 1.7 - lineNumber(whileNode); 1.8 - 1.9 final Expression test = whileNode.getTest(); 1.10 final Block body = whileNode.getBody(); 1.11 final Label breakLabel = whileNode.getBreakLabel(); 1.12 final Label continueLabel = whileNode.getContinueLabel(); 1.13 + final boolean isDoWhile = whileNode.isDoWhile(); 1.14 final Label loopLabel = new Label("loop"); 1.15 1.16 - if (!whileNode.isDoWhile()) { 1.17 + if (!isDoWhile) { 1.18 method._goto(continueLabel); 1.19 } 1.20 1.21 @@ -2202,6 +2201,7 @@ 1.22 body.accept(this); 1.23 if (!whileNode.isTerminal()) { 1.24 method.label(continueLabel); 1.25 + lineNumber(whileNode); 1.26 new BranchOptimizer(this, method).execute(test, loopLabel, true); 1.27 method.label(breakLabel); 1.28 }
2.1 --- a/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java Sat Nov 16 00:23:46 2013 +0100 2.2 +++ b/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java Mon Nov 18 16:35:39 2013 +0100 2.3 @@ -28,6 +28,7 @@ 2.4 import java.util.List; 2.5 import jdk.nashorn.internal.ir.BinaryNode; 2.6 import jdk.nashorn.internal.ir.Block; 2.7 +import jdk.nashorn.internal.ir.BlockStatement; 2.8 import jdk.nashorn.internal.ir.CaseNode; 2.9 import jdk.nashorn.internal.ir.CatchNode; 2.10 import jdk.nashorn.internal.ir.ExpressionStatement; 2.11 @@ -141,7 +142,6 @@ 2.12 @Override 2.13 public boolean enterBlock(final Block block) { 2.14 sb.append(' '); 2.15 - //sb.append(Debug.id(block)); 2.16 sb.append('{'); 2.17 2.18 indent += TABWIDTH; 2.19 @@ -190,12 +190,17 @@ 2.20 sb.append(EOLN); 2.21 indent(); 2.22 sb.append('}'); 2.23 - // sb.append(Debug.id(block)); 2.24 2.25 return false; 2.26 } 2.27 2.28 @Override 2.29 + public boolean enterBlockStatement(final BlockStatement statement) { 2.30 + statement.getBlock().accept(this); 2.31 + return false; 2.32 + } 2.33 + 2.34 + @Override 2.35 public boolean enterBinaryNode(final BinaryNode binaryNode) { 2.36 binaryNode.lhs().accept(this); 2.37 sb.append(' '); 2.38 @@ -233,7 +238,6 @@ 2.39 public boolean enterFunctionNode(final FunctionNode functionNode) { 2.40 functionNode.toString(sb); 2.41 enterBlock(functionNode.getBody()); 2.42 - //sb.append(EOLN); 2.43 return false; 2.44 } 2.45
3.1 --- a/src/jdk/nashorn/internal/parser/Parser.java Sat Nov 16 00:23:46 2013 +0100 3.2 +++ b/src/jdk/nashorn/internal/parser/Parser.java Mon Nov 18 16:35:39 2013 +0100 3.3 @@ -1210,21 +1210,24 @@ 3.4 */ 3.5 private void whileStatement() { 3.6 // Capture WHILE token. 3.7 - final int whileLine = line; 3.8 final long whileToken = token; 3.9 // WHILE tested in caller. 3.10 next(); 3.11 3.12 // Construct WHILE node. 3.13 - WhileNode whileNode = new WhileNode(whileLine, whileToken, Token.descPosition(whileToken), false); 3.14 + WhileNode whileNode = new WhileNode(line, whileToken, Token.descPosition(whileToken), false); 3.15 lc.push(whileNode); 3.16 3.17 try { 3.18 expect(LPAREN); 3.19 - whileNode = whileNode.setTest(lc, expression()); 3.20 + final int whileLine = line; 3.21 + final Expression test = expression(); 3.22 expect(RPAREN); 3.23 - whileNode = whileNode.setBody(lc, getStatement()); 3.24 - appendStatement(whileNode); 3.25 + final Block body = getStatement(); 3.26 + appendStatement(whileNode = 3.27 + new WhileNode(whileLine, whileToken, finish, false). 3.28 + setTest(lc, test). 3.29 + setBody(lc, body)); 3.30 } finally { 3.31 lc.pop(whileNode); 3.32 } 3.33 @@ -1242,28 +1245,33 @@ 3.34 */ 3.35 private void doStatement() { 3.36 // Capture DO token. 3.37 - final int doLine = line; 3.38 final long doToken = token; 3.39 // DO tested in the caller. 3.40 next(); 3.41 3.42 - WhileNode doWhileNode = new WhileNode(doLine, doToken, Token.descPosition(doToken), true); 3.43 + WhileNode doWhileNode = new WhileNode(-1, doToken, Token.descPosition(doToken), true); 3.44 lc.push(doWhileNode); 3.45 3.46 try { 3.47 // Get DO body. 3.48 - doWhileNode = doWhileNode.setBody(lc, getStatement()); 3.49 + final Block body = getStatement(); 3.50 3.51 expect(WHILE); 3.52 expect(LPAREN); 3.53 - doWhileNode = doWhileNode.setTest(lc, expression()); 3.54 + final int doLine = line; 3.55 + final Expression test = expression(); 3.56 expect(RPAREN); 3.57 3.58 if (type == SEMICOLON) { 3.59 endOfLine(); 3.60 } 3.61 doWhileNode.setFinish(finish); 3.62 - appendStatement(doWhileNode); 3.63 + 3.64 + //line number is last 3.65 + appendStatement(doWhileNode = 3.66 + new WhileNode(doLine, doToken, finish, true). 3.67 + setBody(lc, body). 3.68 + setTest(lc, test)); 3.69 } finally { 3.70 lc.pop(doWhileNode); 3.71 }
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/test/script/basic/JDK-8028434.js Mon Nov 18 16:35:39 2013 +0100 4.3 @@ -0,0 +1,58 @@ 4.4 +/* 4.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.7 + * 4.8 + * This code is free software; you can redistribute it and/or modify it 4.9 + * under the terms of the GNU General Public License version 2 only, as 4.10 + * published by the Free Software Foundation. 4.11 + * 4.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 4.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 4.15 + * version 2 for more details (a copy is included in the LICENSE file that 4.16 + * accompanied this code). 4.17 + * 4.18 + * You should have received a copy of the GNU General Public License version 4.19 + * 2 along with this work; if not, write to the Free Software Foundation, 4.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 4.21 + * 4.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 4.23 + * or visit www.oracle.com if you need additional information or have any 4.24 + * questions. 4.25 + */ 4.26 + 4.27 +/** 4.28 + * JDK-8028434: Check that the line number of the tests in while and do while loops 4.29 + * is correct. It needs to correspond to the line with the test expression. 4.30 + * 4.31 + * @test 4.32 + * @run 4.33 + */ 4.34 + 4.35 +try { 4.36 + while (test.apa < 0) { 4.37 + print("x"); 4.38 + } 4.39 +} catch (e) { 4.40 + var st = e.getStackTrace(); 4.41 + if (st.length != 1) { 4.42 + print("erroneous stacktrace length " + s.length); 4.43 + } 4.44 + if (st[0].lineNumber !== 32) { 4.45 + print("erroneous stacktrace element, lineNumber=" + st[0].lineNumber + " elem=" + st); 4.46 + } 4.47 +} 4.48 + 4.49 +try { 4.50 + do { 4.51 + print("x"); 4.52 + } while (test.apa < 0); 4.53 +} catch (e) { 4.54 + var st = e.getStackTrace(); 4.55 + if (st.length != 1) { 4.56 + print("erroneous stacktrace length " + s.length); 4.57 + } 4.58 + if (st[0].lineNumber !== 48) { 4.59 + print("erroneous stacktrace element, lineNumber= " + st[0].lineNumber + " elem=" + st); 4.60 + } 4.61 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/test/script/basic/JDK-8028434.js.EXPECTED Mon Nov 18 16:35:39 2013 +0100 5.3 @@ -0,0 +1,1 @@ 5.4 +x