# HG changeset patch # User hannesw # Date 1502371157 -7200 # Node ID b385216af0ed3aa21b1c631632b0688afa999cdf # Parent a586a1c1a9e3b460f60a045862b0e2421d6fd195 8185252: Unary minus and plus use wrong node Kind Reviewed-by: sundar, hannesw Contributed-by: priya.lakshmi.muthuswamy@oracle.com diff -r a586a1c1a9e3 -r b385216af0ed nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/TreeImpl.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/TreeImpl.java Tue Aug 08 22:52:18 2017 +0000 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/TreeImpl.java Thu Aug 10 15:19:17 2017 +0200 @@ -75,6 +75,8 @@ return Kind.MULTIPLY; case ASSIGN_MUL: return Kind.MULTIPLY_ASSIGNMENT; + case POS: + return Kind.UNARY_PLUS; case ADD: return Kind.PLUS; case INCPREFIX: @@ -83,6 +85,8 @@ return Kind.POSTFIX_INCREMENT; case ASSIGN_ADD: return Kind.PLUS_ASSIGNMENT; + case NEG: + return Kind.UNARY_MINUS; case SUB: return Kind.MINUS; case DECPREFIX: diff -r a586a1c1a9e3 -r b385216af0ed nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java Tue Aug 08 22:52:18 2017 +0000 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java Thu Aug 10 15:19:17 2017 +0200 @@ -1027,7 +1027,7 @@ } @Override - public boolean enterSUB(final UnaryNode unaryNode) { + public boolean enterNEG(final UnaryNode unaryNode) { loadSUB(unaryNode, resultBounds); return false; } @@ -1105,7 +1105,7 @@ } @Override - public boolean enterADD(final UnaryNode unaryNode) { + public boolean enterPOS(final UnaryNode unaryNode) { loadADD(unaryNode, resultBounds); return false; } diff -r a586a1c1a9e3 -r b385216af0ed nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FoldConstants.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FoldConstants.java Tue Aug 08 22:52:18 2017 +0000 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FoldConstants.java Thu Aug 10 15:19:17 2017 +0200 @@ -231,7 +231,7 @@ LiteralNode literalNode; switch (parent.tokenType()) { - case ADD: + case POS: if (rhsInteger) { literalNode = LiteralNode.newInstance(token, finish, rhs.getInt32()); } else if (rhsType.isLong()) { @@ -240,7 +240,7 @@ literalNode = LiteralNode.newInstance(token, finish, rhs.getNumber()); } break; - case SUB: + case NEG: if (rhsInteger && rhs.getInt32() != 0) { // @see test/script/basic/minuszero.js literalNode = LiteralNode.newInstance(token, finish, -rhs.getInt32()); } else if (rhsType.isLong() && rhs.getLong() != 0L) { diff -r a586a1c1a9e3 -r b385216af0ed nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/WeighNodes.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/WeighNodes.java Tue Aug 08 22:52:18 2017 +0000 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/WeighNodes.java Thu Aug 10 15:19:17 2017 +0200 @@ -317,7 +317,7 @@ } @Override - public Node leaveADD(final UnaryNode unaryNode) { + public Node leavePOS(final UnaryNode unaryNode) { return unaryNodeWeight(unaryNode); } @@ -348,7 +348,7 @@ } @Override - public Node leaveSUB(final UnaryNode unaryNode) { + public Node leaveNEG(final UnaryNode unaryNode) { return unaryNodeWeight(unaryNode); } diff -r a586a1c1a9e3 -r b385216af0ed nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/UnaryNode.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/UnaryNode.java Tue Aug 08 22:52:18 2017 +0000 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/UnaryNode.java Thu Aug 10 15:19:17 2017 +0200 @@ -58,8 +58,8 @@ private static final List CAN_OVERFLOW = Collections.unmodifiableList( Arrays.asList(new TokenType[] { - TokenType.ADD, - TokenType.SUB, //negate + TokenType.POS, + TokenType.NEG, //negate TokenType.DECPREFIX, TokenType.DECPOSTFIX, TokenType.INCPREFIX, @@ -125,7 +125,7 @@ @Override public Type getWidestOperationType() { switch (tokenType()) { - case ADD: + case POS: final Type operandType = getExpression().getType(); if(operandType == Type.BOOLEAN) { return Type.INT; @@ -134,7 +134,7 @@ } assert operandType.isNumeric(); return operandType; - case SUB: + case NEG: // This might seems overly conservative until you consider that -0 can only be represented as a double. return Type.NUMBER; case NOT: @@ -182,8 +182,8 @@ switch (tokenType()) { case NEW: return false; - case ADD: - case SUB: + case POS: + case NEG: case NOT: case BIT_NOT: return expression.isLocal() && expression.getType().isJSPrimitive(); diff -r a586a1c1a9e3 -r b385216af0ed nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java Tue Aug 08 22:52:18 2017 +0000 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java Thu Aug 10 15:19:17 2017 +0200 @@ -47,8 +47,8 @@ @Override public boolean enterUnaryNode(final UnaryNode unaryNode) { switch (unaryNode.tokenType()) { - case ADD: - return enterADD(unaryNode); + case POS: + return enterPOS(unaryNode); case BIT_NOT: return enterBIT_NOT(unaryNode); case DELETE: @@ -57,8 +57,8 @@ return enterNEW(unaryNode); case NOT: return enterNOT(unaryNode); - case SUB: - return enterSUB(unaryNode); + case NEG: + return enterNEG(unaryNode); case TYPEOF: return enterTYPEOF(unaryNode); case VOID: @@ -76,8 +76,8 @@ @Override public final Node leaveUnaryNode(final UnaryNode unaryNode) { switch (unaryNode.tokenType()) { - case ADD: - return leaveADD(unaryNode); + case POS: + return leavePOS(unaryNode); case BIT_NOT: return leaveBIT_NOT(unaryNode); case DELETE: @@ -86,8 +86,8 @@ return leaveNEW(unaryNode); case NOT: return leaveNOT(unaryNode); - case SUB: - return leaveSUB(unaryNode); + case NEG: + return leaveNEG(unaryNode); case TYPEOF: return leaveTYPEOF(unaryNode); case VOID: @@ -280,7 +280,7 @@ * @param unaryNode the node * @return true if traversal should continue and node children be traversed, false otherwise */ - public boolean enterADD(final UnaryNode unaryNode) { + public boolean enterPOS(final UnaryNode unaryNode) { return enterDefault(unaryNode); } @@ -290,7 +290,7 @@ * @param unaryNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leaveADD(final UnaryNode unaryNode) { + public Node leavePOS(final UnaryNode unaryNode) { return leaveDefault(unaryNode); } @@ -400,7 +400,7 @@ * @param unaryNode the node * @return true if traversal should continue and node children be traversed, false otherwise */ - public boolean enterSUB(final UnaryNode unaryNode) { + public boolean enterNEG(final UnaryNode unaryNode) { return enterDefault(unaryNode); } @@ -410,7 +410,7 @@ * @param unaryNode the node * @return processed node, which will replace the original one, or the original node */ - public Node leaveSUB(final UnaryNode unaryNode) { + public Node leaveNEG(final UnaryNode unaryNode) { return leaveDefault(unaryNode); } diff -r a586a1c1a9e3 -r b385216af0ed nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java Tue Aug 08 22:52:18 2017 +0000 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java Thu Aug 10 15:19:17 2017 +0200 @@ -4391,10 +4391,15 @@ appendStatement(new ExpressionStatement(unaryLine, unaryToken, finish, expr)); return LiteralNode.newInstance(unaryToken, finish, true); } + case ADD: + case SUB: { + final TokenType opType = type; + next(); + final Expression expr = unaryExpression(); + return new UnaryNode(Token.recast(unaryToken, (opType == TokenType.ADD) ? TokenType.POS : TokenType.NEG), expr); + } case VOID: case TYPEOF: - case ADD: - case SUB: case BIT_NOT: case NOT: next(); diff -r a586a1c1a9e3 -r b385216af0ed nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/TokenType.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/TokenType.java Tue Aug 08 22:52:18 2017 +0000 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/TokenType.java Thu Aug 10 15:19:17 2017 +0200 @@ -63,10 +63,12 @@ RPAREN (BRACKET, ")", 0, true), MUL (BINARY, "*", 13, true), ASSIGN_MUL (BINARY, "*=", 2, false), + POS (UNARY, "+", 14, false), ADD (BINARY, "+", 12, true), INCPREFIX (UNARY, "++", 15, true), ASSIGN_ADD (BINARY, "+=", 2, false), COMMARIGHT (BINARY, ",", 1, true), + NEG (UNARY, "-", 14, false), SUB (BINARY, "-", 12, true), DECPREFIX (UNARY, "--", 15, true), ASSIGN_SUB (BINARY, "-=", 2, false), diff -r a586a1c1a9e3 -r b385216af0ed nashorn/test/script/nosecurity/JDK-8185252.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/nosecurity/JDK-8185252.js Thu Aug 10 15:19:17 2017 +0200 @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2017, 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. + */ + +/** + * Test that Unary minus and plus uses UNARY_MINUS and UNARY_PLUS node Kind + * + * @test + * @bug 8185252 + * @option -scripting + * @run + */ + +var parser = Java.type('jdk.nashorn.api.tree.Parser'); +var tree = Java.type('jdk.nashorn.api.tree.Tree'); +var list = Java.type('java.util.List'); +var visitor = Java.type('jdk.nashorn.api.tree.SimpleTreeVisitorES5_1'); +var cls = Java.type('java.lang.Class') + +function convert (value) { + if (!value || typeof(value) != 'object') { + return value; + } + var obj = Object.bindProperties({}, value) + var result = {} + for (var i in obj) { + if (i == "lineMap") { + continue; + } + + var val = obj[i] + // skip these ES6 specific properties to reduce noise + // in the output - unless there were set to true + if (typeof(val) == 'boolean' && val == false) { + switch (i) { + case "computed": + case "static": + case "restParameter": + case "this": + case "super": + case "star": + case "default": + case "starDefaultStar": + case "arrow": + case "generator": + case "let": + case "const": + continue; + } + } + + if (typeof(val) == 'object') { + if (val instanceof cls) { + continue; + } + if (val instanceof tree) { + result[i] = convert(val) + } + else if (val instanceof list) { + var lst = [] + for (var j in val) { + lst.push(convert(val[j])) + } + result[i] = lst + } + else { + result[i] = String(val) + } + } else if (typeof(val) != 'function') { + result[i] = String(val) + } + } + return result +} + +function parse(name, code, args, visitor, listener) { + var tree = parser.create(args).parse(name, code, listener || null) + var results = [] + tree.accept(visitor, results) + print(JSON.stringify(results, null, 2)) +} + + +var code = <