Mercurial > hg > openjdk > aarch64-port > nashorn
changeset 1487:676ce2f6b277
Merge
author | asaha |
---|---|
date | Wed, 03 Jun 2015 20:30:20 -0700 |
parents | dc07d2b95013 (current diff) 3780124b6dbb (diff) |
children | eb0e45a0f6d0 |
files | .hgtags src/jdk/nashorn/internal/runtime/JSObjectListAdapter.java |
diffstat | 53 files changed, 1579 insertions(+), 344 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Thu May 28 20:55:21 2015 -0700 +++ b/.hgtags Wed Jun 03 20:30:20 2015 -0700 @@ -422,3 +422,4 @@ 78fcf7f0eac8ffa474518b315bdf84a1dbd6e76d jdk8u60-b15 bf44ade6c2c2e697ccbc1e57f3eac870908614e6 jdk8u60-b16 ff7052ce0f6b655d726cd0f77e9a5f8313361889 jdk8u60-b17 +0b5c0f02a0b79ae0aa97520d65e5b520af8f1b2a jdk8u60-b18
--- a/make/build.xml Thu May 28 20:55:21 2015 -0700 +++ b/make/build.xml Wed Jun 03 20:30:20 2015 -0700 @@ -210,7 +210,7 @@ </target> <target name="javadoc" depends="jar"> - <javadoc destdir="${dist.javadoc.dir}" use="yes" overview="src/overview.html" + <javadoc destdir="${dist.javadoc.dir}" use="yes" overview="${src.dir}/overview.html" extdirs="${nashorn.ext.path}" windowtitle="${nashorn.product.name} ${nashorn.version}" additionalparam="-quiet" failonerror="true"> <classpath> @@ -460,7 +460,7 @@ </testng> </target> - <target name="test" depends="test-pessimistic, test-optimistic"/> + <target name="test" depends="javadoc, test-pessimistic, test-optimistic"/> <target name="test-optimistic" depends="jar, -test-classes-all,-test-classes-single, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available"> <echo message="Running test suite in OPTIMISTIC mode..."/>
--- a/samples/browser_dom.js Thu May 28 20:55:21 2015 -0700 +++ b/samples/browser_dom.js Wed Jun 03 20:30:20 2015 -0700 @@ -40,7 +40,6 @@ var ChangeListener = Java.type("javafx.beans.value.ChangeListener"); var Scene = Java.type("javafx.scene.Scene"); var WebView = Java.type("javafx.scene.web.WebView"); -var EventListener = Java.type("org.w3c.dom.events.EventListener"); // JavaFX start method function start(stage) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/samples/console.js Wed Jun 03 20:30:20 2015 -0700 @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * Simple Web Console-like support for Nashorn. In addition to + * Web console object methods, this console add methods of + * java.io.Console as well. Note:not all web console methods are + * implemented but useful subset is implemented. + * + * See also: https://developer.mozilla.org/en/docs/Web/API/console + */ + + +if (typeof console == 'undefined') { + +(function() { + var LocalDateTime = Java.type("java.time.LocalDateTime"); + var System = Java.type("java.lang.System"); + var jconsole = System.console(); + + // add a new global variable called "console" + this.console = { + }; + + function addConsoleMethods() { + // expose methods of java.io.Console as an extension + var placeholder = "-*-"; + // put a placeholder for each name from java.lang.Object + var objMethods = Object.bindProperties({}, new java.lang.Object()); + for (var m in objMethods) { + console[m] = placeholder; + } + + // bind only the methods of java.io.Console + // This bind will skip java.lang.Object methods as console + // has properties of same name. + Object.bindProperties(console, jconsole); + + // Now, delete java.lang.Object methods + for (var m in console) { + if (console[m] == placeholder) { + delete console[m]; + } + } + } + + addConsoleMethods(); + + function consoleLog(type, msg) { + // print type of message, then time. + jconsole.format("%s [%s] ", type, LocalDateTime.now().toString()); + if (typeof msg == 'string') { + jconsole.format(msg + "\n", Array.prototype.slice.call(arguments, 2)); + } else { + // simple space separated values and newline at the end + var arr = Array.prototype.slice.call(arguments, 1); + jconsole.format("%s\n", arr.join(" ")); + } + } + + console.toString = function() "[object Console]"; + + // web console functions + + console.assert = function(expr) { + if (! expr) { + arguments[0] = "Assertion Failed:"; + consoleLog.apply(console, arguments); + // now, stack trace at the end + jconsole.format("%s\n", new Error().stack); + } + }; + + // dummy clear to avoid error! + console.clear = function() {}; + + var counter = { + get: function(label) { + if (! this[label]) { + return this[label] = 1; + } else { + return ++this[label]; + } + } + }; + + // counter + console.count = function(label) { + label = label? String(label) : "<no label>"; + jconsole.format("%s: %d\n",label, counter.get(label).intValue()); + } + + // logging + console.error = consoleLog.bind(jconsole, "ERROR"); + console.info = consoleLog.bind(jconsole, "INFO"); + console.log = console.info; + console.debug = console.log; + console.warn = consoleLog.bind(jconsole, "WARNING"); + + // print stack trace + console.trace = function() { + jconsole.format("%s\n", new Error().stack); + }; +})(); + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/samples/consoleuse.js Wed Jun 03 20:30:20 2015 -0700 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +load(__DIR__ + "console.js"); + +console.log("consoleuse.js started!"); + +function func() { + console.count("func"); +} + + +func(); +func(); +func(); +func(); + +// java.io.Console method +console.readPassword("passworld please: "); +console.error("Big error: %s!", "you revealed your password!"); +console.warn("You've done this %d times", 345); +console.assert(arguments.length != 0, "no arguments!"); + +// java.io.Console methods +var str = console.readLine("enter something: "); +console.printf("you entered: %s\n", str); +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/samples/time_color.fx Wed Jun 03 20:30:20 2015 -0700 @@ -0,0 +1,89 @@ +#// Usage: jjs -fx time_color.js [-- true/false] + +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// A simple javafx program that changes background color +// of scene based on current time value (once per sec). +// inspired by http://whatcolourisit.scn9a.org/ + +if (!$OPTIONS._fx) { + print("Usage: jjs -fx time_color.js"); + print(" jjs -fx time_color.js -- true"); + exit(1); +} + +// JavaFX classes used +var Color = Java.type("javafx.scene.paint.Color"); +var Group = Java.type("javafx.scene.Group"); +var Label = Java.type("javafx.scene.control.Label"); +var Platform = Java.type("javafx.application.Platform"); +var Scene = Java.type("javafx.scene.Scene"); +var Timer = Java.type("java.util.Timer"); + +// execute function periodically once per given time in millisec +function setInterval(func, ms) { + // New timer, run as daemon so the application can quit + var timer = new Timer("setInterval", true); + timer.schedule(function() Platform.runLater(func), ms, ms); + return timer; +} + +// do you want to flip hour/min/sec for RGB? +var flip = arguments.length > 0? "true".equals(arguments[0]) : false; + +// JavaFX start method +function start(stage) { + start.title = "Time Color"; + var root = new Group(); + var label = new Label("time"); + label.textFill = Color.WHITE; + root.children.add(label); + stage.scene = new Scene(root, 700, 500); + + setInterval(function() { + var d = new Date(); + var hours = d.getHours(); + var mins = d.getMinutes(); + var secs = d.getSeconds(); + + if (hours < 10) hours = "0" + hours; + if (mins < 10) mins = "0" + mins; + if (secs < 10) secs = "0" + secs; + + var hex = flip? + "#" + secs + mins + hours : "#" + hours + mins + secs; + label.text = "Color: " + hex; + stage.scene.fill = Color.web(hex); + }, 1000); + + stage.show(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/samples/undefined_call.js Wed Jun 03 20:30:20 2015 -0700 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// Nashorn extension: __noSuchMethod__ +// See also: https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions#Nashornextensions-__noSuchMethod__ + +Object.prototype.__noSuchMethod__ = function(name) { + print(name + " function is not defined in " + this); + + // Nashorn extension: stack property + // gives stack trace as a string + print(new Error().stack); +} + +function func(obj) { + obj.foo(); +} + +func({}); +func(this);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/samples/unzip.js Wed Jun 03 20:30:20 2015 -0700 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Simple unzip tool using #nashorn and #java + * zip fs file system interface. + */ + +if (arguments.length == 0) { + print("Usage: jjs zipfs.js -- <.zip/.jar file> [out dir]"); + exit(1); +} + +var File = Java.type("java.io.File"); +// output directory where zip is extracted +var outDir = arguments[1]; +if (!outDir) { + outDir = "."; +} else { + if (! new File(outDir).isDirectory()) { + print(outDir + " directory does not exist!"); + exit(1); + } +} + +var Files = Java.type("java.nio.file.Files"); +var FileSystems = Java.type("java.nio.file.FileSystems"); +var Paths = Java.type("java.nio.file.Paths"); + +var zipfile = Paths.get(arguments[0]) +var fs = FileSystems.newFileSystem(zipfile, null); +var root = fs.rootDirectories[0]; + +// walk root and handle each Path +Files.walk(root).forEach( + function(p) { + var outPath = outDir + + p.toString().replace('/', File.separatorChar); + print(outPath); + if (Files.isDirectory(p)) { + // create directories as needed + new File(outPath).mkdirs(); + } else { + // copy a 'file' resource + Files.copy(p, new File(outPath).toPath()); + } + } +); + +// done +fs.close();
--- a/src/jdk/nashorn/internal/codegen/AssignSymbols.java Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/codegen/AssignSymbols.java Wed Jun 03 20:30:20 2015 -0700 @@ -84,6 +84,7 @@ import jdk.nashorn.internal.ir.VarNode; import jdk.nashorn.internal.ir.WithNode; import jdk.nashorn.internal.ir.visitor.NodeVisitor; +import jdk.nashorn.internal.parser.TokenType; import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.ECMAErrors; import jdk.nashorn.internal.runtime.ErrorManager; @@ -714,12 +715,10 @@ @Override public Node leaveBinaryNode(final BinaryNode binaryNode) { - switch (binaryNode.tokenType()) { - case ASSIGN: + if (binaryNode.isTokenType(TokenType.ASSIGN)) { return leaveASSIGN(binaryNode); - default: - return super.leaveBinaryNode(binaryNode); } + return super.leaveBinaryNode(binaryNode); } private Node leaveASSIGN(final BinaryNode binaryNode) {
--- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java Wed Jun 03 20:30:20 2015 -0700 @@ -3798,7 +3798,6 @@ emitBranch(binaryNode, onTrue, true); if (isCurrentDiscard) { method.label(onTrue); - method.pop(); } else { method.load(false); method._goto(skip);
--- a/src/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java Wed Jun 03 20:30:20 2015 -0700 @@ -459,7 +459,7 @@ // NOTE: regardless of operator's lexical associativity, lhs is always evaluated first. final Expression lhs = binaryNode.lhs(); final LvarType lhsType; - if (!(lhs instanceof IdentNode && binaryNode.tokenType() == TokenType.ASSIGN)) { + if (!(lhs instanceof IdentNode && binaryNode.isTokenType(TokenType.ASSIGN))) { lhsType = visitExpression(lhs); } else { // Can't visit IdentNode on LHS of a simple assignment, as visits imply use, and this is def.
--- a/src/jdk/nashorn/internal/codegen/Lower.java Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/codegen/Lower.java Wed Jun 03 20:30:20 2015 -0700 @@ -200,7 +200,7 @@ final String name = getConstantPropertyName(indexNode.getIndex()); if (name != null) { // If index node is a constant property name convert index node to access node. - assert Token.descType(indexNode.getToken()) == TokenType.LBRACKET; + assert indexNode.isIndex(); return new AccessNode(indexNode.getToken(), indexNode.getFinish(), indexNode.getBase(), name); } return super.leaveIndexNode(indexNode);
--- a/src/jdk/nashorn/internal/codegen/OptimisticTypesPersistence.java Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/codegen/OptimisticTypesPersistence.java Wed Jun 03 20:30:20 2015 -0700 @@ -61,7 +61,7 @@ import jdk.nashorn.internal.runtime.options.Options; /** - * Static utility that encapsulates persistence of type information for functions compiled with optimistic + * <p>Static utility that encapsulates persistence of type information for functions compiled with optimistic * typing. With this feature enabled, when a JavaScript function is recompiled because it gets deoptimized, * the type information for deoptimization is stored in a cache file. If the same function is compiled in a * subsequent JVM invocation, the type information is used for initial compilation, thus allowing the system @@ -77,6 +77,7 @@ * {@code nashorn.typeInfo.cleanupDelaySeconds} system property. You can also specify the word * {@code unlimited} as the value for {@code nashorn.typeInfo.maxFiles} in which case the type info cache is * allowed to grow without limits. + * </p> */ public final class OptimisticTypesPersistence { // Default is 0, for disabling the feature when not specified. A reasonable default when enabled is
--- a/src/jdk/nashorn/internal/ir/AccessNode.java Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/ir/AccessNode.java Wed Jun 03 20:30:20 2015 -0700 @@ -28,8 +28,6 @@ import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.annotations.Immutable; import jdk.nashorn.internal.ir.visitor.NodeVisitor; -import jdk.nashorn.internal.parser.Token; -import jdk.nashorn.internal.parser.TokenType; /** * IR representation of a property access (period operator.) @@ -103,14 +101,6 @@ return property; } - /** - * Return true if this node represents an index operation normally represented as {@link IndexNode}. - * @return true if an index access. - */ - public boolean isIndex() { - return Token.descType(getToken()) == TokenType.LBRACKET; - } - private AccessNode setBase(final Expression base) { if (this.base == base) { return this;
--- a/src/jdk/nashorn/internal/ir/BaseNode.java Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/ir/BaseNode.java Wed Jun 03 20:30:20 2015 -0700 @@ -29,6 +29,7 @@ import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.annotations.Immutable; +import jdk.nashorn.internal.parser.TokenType; /** * IR base for accessing/indexing nodes. @@ -122,6 +123,14 @@ } /** + * Return true if this node represents an index operation normally represented as {@link IndexNode}. + * @return true if an index access. + */ + public boolean isIndex() { + return isTokenType(TokenType.LBRACKET); + } + + /** * Mark this node as being the callee operand of a {@link CallNode}. * @return a base node identical to this one in all aspects except with its function flag set. */
--- a/src/jdk/nashorn/internal/ir/BinaryNode.java Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/ir/BinaryNode.java Wed Jun 03 20:30:20 2015 -0700 @@ -312,7 +312,7 @@ @Override public boolean isSelfModifying() { - return isAssignment() && tokenType() != TokenType.ASSIGN; + return isAssignment() && !isTokenType(TokenType.ASSIGN); } @Override @@ -529,7 +529,7 @@ final TokenType tokenType = tokenType(); if(tokenType == TokenType.ADD || tokenType == TokenType.ASSIGN_ADD) { return OPTIMISTIC_UNDECIDED_TYPE; - } else if (CAN_OVERFLOW.contains(tokenType())) { + } else if (CAN_OVERFLOW.contains(tokenType)) { return Type.INT; } return getMostPessimisticType();
--- a/src/jdk/nashorn/internal/ir/LexicalContext.java Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/ir/LexicalContext.java Wed Jun 03 20:30:20 2015 -0700 @@ -204,7 +204,7 @@ /** * Explicitly apply flags to the topmost element on the stack. This is only valid to use from a * {@code NodeVisitor.leaveXxx()} method and only on the node being exited at the time. It is not mandatory to use, - * as {@link #pop(LexicalContextNode)} will apply the flags automatically, but this method can be used to apply them + * as {@link #pop(Node)} will apply the flags automatically, but this method can be used to apply them * during the {@code leaveXxx()} method in case its logic depends on the value of the flags. * @param node the node to apply the flags to. Must be the topmost node on the stack. * @return the passed in node, or a modified node (if any flags were modified)
--- a/src/jdk/nashorn/internal/ir/Node.java Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/ir/Node.java Wed Jun 03 20:30:20 2015 -0700 @@ -220,26 +220,28 @@ } /** - * Return token tokenType from a token descriptor. + * Returns this node's token's type. If you want to check for the node having a specific token type, + * consider using {@link #isTokenType(TokenType)} instead. * - * @return Type of token. + * @return type of token. */ public TokenType tokenType() { return Token.descType(token); } /** - * Test token tokenType. + * Tests if this node has the specific token type. * - * @param type a type to check this token against + * @param type a token type to check this node's token type against * @return true if token types match. */ public boolean isTokenType(final TokenType type) { - return Token.descType(token) == type; + return tokenType() == type; } /** - * Get the token for this location + * Get the token for this node. If you want to retrieve the token's type, consider using + * {@link #tokenType()} or {@link #isTokenType(TokenType)} instead. * @return the token */ public long getToken() {
--- a/src/jdk/nashorn/internal/ir/TryNode.java Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/ir/TryNode.java Wed Jun 03 20:30:20 2015 -0700 @@ -57,7 +57,7 @@ * block was not terminal; the original jump/return is simply ignored if the finally block itself * terminates). The reason for this somewhat strange arrangement is that we didn't want to create a * separate class for the (label, BlockStatement pair) but rather reused the already available LabelNode. - * However, if we simply used List<LabelNode> without wrapping the label nodes in an additional Block, + * However, if we simply used List<LabelNode> without wrapping the label nodes in an additional Block, * that would've thrown off visitors relying on BlockLexicalContext -- same reason why we never use * Statement as the type of bodies of e.g. IfNode, WhileNode etc. but rather blockify them even when they're * single statements.
--- a/src/jdk/nashorn/internal/ir/VarNode.java Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/ir/VarNode.java Wed Jun 03 20:30:20 2015 -0700 @@ -27,7 +27,6 @@ import jdk.nashorn.internal.ir.annotations.Immutable; import jdk.nashorn.internal.ir.visitor.NodeVisitor; -import jdk.nashorn.internal.parser.Token; /** * Node represents a var/let declaration. @@ -182,7 +181,7 @@ @Override public void toString(final StringBuilder sb, final boolean printType) { - sb.append(Token.descType(getToken()).getName()).append(' '); + sb.append(tokenType().getName()).append(' '); name.toString(sb, printType); if (init != null) {
--- a/src/jdk/nashorn/internal/objects/Global.java Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/objects/Global.java Wed Jun 03 20:30:20 2015 -0700 @@ -220,7 +220,12 @@ @Property(name = "Number", attributes = Attribute.NOT_ENUMERABLE) public volatile Object number; - /** ECMA 15.1.4.7 Date constructor */ + /** + * Getter for ECMA 15.1.4.7 Date property + * + * @param self self reference + * @return Date property value + */ @Getter(name = "Date", attributes = Attribute.NOT_ENUMERABLE) public static Object getDate(final Object self) { final Global global = Global.instanceFrom(self); @@ -230,6 +235,12 @@ return global.date; } + /** + * Setter for ECMA 15.1.4.7 Date property + * + * @param self self reference + * @param value value for the Date property + */ @Setter(name = "Date", attributes = Attribute.NOT_ENUMERABLE) public static void setDate(final Object self, final Object value) { final Global global = Global.instanceFrom(self); @@ -238,7 +249,12 @@ private volatile Object date = LAZY_SENTINEL; - /** ECMA 15.1.4.8 RegExp constructor */ + /** + * Getter for ECMA 15.1.4.8 RegExp property + * + * @param self self reference + * @return RegExp property value + */ @Getter(name = "RegExp", attributes = Attribute.NOT_ENUMERABLE) public static Object getRegExp(final Object self) { final Global global = Global.instanceFrom(self); @@ -248,6 +264,12 @@ return global.regexp; } + /** + * Setter for ECMA 15.1.4.8 RegExp property + * + * @param self self reference + * @param value value for the RegExp property + */ @Setter(name = "RegExp", attributes = Attribute.NOT_ENUMERABLE) public static void setRegExp(final Object self, final Object value) { final Global global = Global.instanceFrom(self); @@ -256,7 +278,11 @@ private volatile Object regexp = LAZY_SENTINEL; - /** ECMA 15.12 - The JSON object */ + /** + * Getter for ECMA 15.12 - The JSON property + * @param self self reference + * @return the value of JSON property + */ @Getter(name = "JSON", attributes = Attribute.NOT_ENUMERABLE) public static Object getJSON(final Object self) { final Global global = Global.instanceFrom(self); @@ -266,6 +292,11 @@ return global.json; } + /** + * Setter for ECMA 15.12 - The JSON property + * @param self self reference + * @param value value for the JSON property + */ @Setter(name = "JSON", attributes = Attribute.NOT_ENUMERABLE) public static void setJSON(final Object self, final Object value) { final Global global = Global.instanceFrom(self); @@ -274,7 +305,11 @@ private volatile Object json = LAZY_SENTINEL; - /** Nashorn extension: global.JSAdapter */ + /** + * Getter for Nashorn extension: global.JSAdapter + * @param self self reference + * @return value of the JSAdapter property + */ @Getter(name = "JSAdapter", attributes = Attribute.NOT_ENUMERABLE) public static Object getJSAdapter(final Object self) { final Global global = Global.instanceFrom(self); @@ -284,6 +319,11 @@ return global.jsadapter; } + /** + * Setter for Nashorn extension: global.JSAdapter + * @param self self reference + * @param value value for the JSAdapter property + */ @Setter(name = "JSAdapter", attributes = Attribute.NOT_ENUMERABLE) public static void setJSAdapter(final Object self, final Object value) { final Global global = Global.instanceFrom(self); @@ -300,7 +340,11 @@ @Property(name = "Error", attributes = Attribute.NOT_ENUMERABLE) public volatile Object error; - /** EvalError object */ + /** + * Getter for the EvalError property + * @param self self reference + * @return the value of EvalError property + */ @Getter(name = "EvalError", attributes = Attribute.NOT_ENUMERABLE) public static Object getEvalError(final Object self) { final Global global = Global.instanceFrom(self); @@ -310,6 +354,11 @@ return global.evalError; } + /** + * Setter for the EvalError property + * @param self self reference + * @param value value of the EvalError property + */ @Setter(name = "EvalError", attributes = Attribute.NOT_ENUMERABLE) public static void setEvalError(final Object self, final Object value) { final Global global = Global.instanceFrom(self); @@ -318,7 +367,11 @@ private volatile Object evalError = LAZY_SENTINEL; - /** RangeError object */ + /** + * Getter for the RangeError property. + * @param self self reference + * @return the value of RangeError property + */ @Getter(name = "RangeError", attributes = Attribute.NOT_ENUMERABLE) public static Object getRangeError(final Object self) { final Global global = Global.instanceFrom(self); @@ -328,6 +381,12 @@ return global.rangeError; } + + /** + * Setter for the RangeError property. + * @param self self reference + * @param value value for the RangeError property + */ @Setter(name = "RangeError", attributes = Attribute.NOT_ENUMERABLE) public static void setRangeError(final Object self, final Object value) { final Global global = Global.instanceFrom(self); @@ -348,7 +407,11 @@ @Property(name = "TypeError", attributes = Attribute.NOT_ENUMERABLE) public volatile Object typeError; - /** URIError object */ + /** + * Getter for the URIError property. + * @param self self reference + * @return the value of URIError property + */ @Getter(name = "URIError", attributes = Attribute.NOT_ENUMERABLE) public static Object getURIError(final Object self) { final Global global = Global.instanceFrom(self); @@ -358,6 +421,11 @@ return global.uriError; } + /** + * Setter for the URIError property. + * @param self self reference + * @param value value for the URIError property + */ @Setter(name = "URIError", attributes = Attribute.NOT_ENUMERABLE) public static void setURIError(final Object self, final Object value) { final Global global = Global.instanceFrom(self); @@ -366,7 +434,11 @@ private volatile Object uriError = LAZY_SENTINEL; - /** ArrayBuffer object */ + /** + * Getter for the ArrayBuffer property. + * @param self self reference + * @return the value of the ArrayBuffer property + */ @Getter(name = "ArrayBuffer", attributes = Attribute.NOT_ENUMERABLE) public static Object getArrayBuffer(final Object self) { final Global global = Global.instanceFrom(self); @@ -376,6 +448,11 @@ return global.arrayBuffer; } + /** + * Setter for the ArrayBuffer property. + * @param self self reference + * @param value value of the ArrayBuffer property + */ @Setter(name = "ArrayBuffer", attributes = Attribute.NOT_ENUMERABLE) public static void setArrayBuffer(final Object self, final Object value) { final Global global = Global.instanceFrom(self); @@ -384,7 +461,11 @@ private volatile Object arrayBuffer; - /** DataView object */ + /** + * Getter for the DataView property. + * @param self self reference + * @return the value of the DataView property + */ @Getter(name = "DataView", attributes = Attribute.NOT_ENUMERABLE) public static Object getDataView(final Object self) { final Global global = Global.instanceFrom(self); @@ -394,6 +475,12 @@ return global.dataView; } + + /** + * Setter for the DataView property. + * @param self self reference + * @param value value of the DataView property + */ @Setter(name = "DataView", attributes = Attribute.NOT_ENUMERABLE) public static void setDataView(final Object self, final Object value) { final Global global = Global.instanceFrom(self); @@ -402,7 +489,11 @@ private volatile Object dataView; - /** TypedArray (int8) */ + /** + * Getter for the Int8Array property. + * @param self self reference + * @return the value of the Int8Array property. + */ @Getter(name = "Int8Array", attributes = Attribute.NOT_ENUMERABLE) public static Object getInt8Array(final Object self) { final Global global = Global.instanceFrom(self); @@ -412,6 +503,11 @@ return global.int8Array; } + /** + * Setter for the Int8Array property. + * @param self self reference + * @param value value of the Int8Array property + */ @Setter(name = "Int8Array", attributes = Attribute.NOT_ENUMERABLE) public static void setInt8Array(final Object self, final Object value) { final Global global = Global.instanceFrom(self); @@ -420,7 +516,11 @@ private volatile Object int8Array; - /** TypedArray (uint8) */ + /** + * Getter for the Uin8Array property. + * @param self self reference + * @return the value of the Uint8Array property + */ @Getter(name = "Uint8Array", attributes = Attribute.NOT_ENUMERABLE) public static Object getUint8Array(final Object self) { final Global global = Global.instanceFrom(self); @@ -430,6 +530,11 @@ return global.uint8Array; } + /** + * Setter for the Uin8Array property. + * @param self self reference + * @param value value of the Uin8Array property + */ @Setter(name = "Uint8Array", attributes = Attribute.NOT_ENUMERABLE) public static void setUint8Array(final Object self, final Object value) { final Global global = Global.instanceFrom(self); @@ -438,7 +543,11 @@ private volatile Object uint8Array; - /** TypedArray (uint8) - Clamped */ + /** + * Getter for the Uint8ClampedArray property. + * @param self self reference + * @return the value of the Uint8ClampedArray property + */ @Getter(name = "Uint8ClampedArray", attributes = Attribute.NOT_ENUMERABLE) public static Object getUint8ClampedArray(final Object self) { final Global global = Global.instanceFrom(self); @@ -448,6 +557,11 @@ return global.uint8ClampedArray; } + /** + * Setter for the Uint8ClampedArray property. + * @param self self reference + * @param value value of the Uint8ClampedArray property + */ @Setter(name = "Uint8ClampedArray", attributes = Attribute.NOT_ENUMERABLE) public static void setUint8ClampedArray(final Object self, final Object value) { final Global global = Global.instanceFrom(self); @@ -456,7 +570,11 @@ private volatile Object uint8ClampedArray; - /** TypedArray (int16) */ + /** + * Getter for the Int16Array property. + * @param self self reference + * @return the value of the Int16Array property + */ @Getter(name = "Int16Array", attributes = Attribute.NOT_ENUMERABLE) public static Object getInt16Array(final Object self) { final Global global = Global.instanceFrom(self); @@ -466,6 +584,11 @@ return global.int16Array; } + /** + * Setter for the Int16Array property. + * @param self self reference + * @param value value of the Int16Array property + */ @Setter(name = "Int16Array", attributes = Attribute.NOT_ENUMERABLE) public static void setInt16Array(final Object self, final Object value) { final Global global = Global.instanceFrom(self); @@ -474,7 +597,11 @@ private volatile Object int16Array; - /** TypedArray (uint16) */ + /** + * Getter for the Uint16Array property. + * @param self self reference + * @return the value of the Uint16Array property + */ @Getter(name = "Uint16Array", attributes = Attribute.NOT_ENUMERABLE) public static Object getUint16Array(final Object self) { final Global global = Global.instanceFrom(self); @@ -484,6 +611,11 @@ return global.uint16Array; } + /** + * Setter for the Uint16Array property. + * @param self self reference + * @param value value of the Uint16Array property + */ @Setter(name = "Uint16Array", attributes = Attribute.NOT_ENUMERABLE) public static void setUint16Array(final Object self, final Object value) { final Global global = Global.instanceFrom(self); @@ -492,7 +624,12 @@ private volatile Object uint16Array; - /** TypedArray (int32) */ + /** + * Getter for the Int32Array property. + * + * @param self self reference + * @return the value of the Int32Array property + */ @Getter(name = "Int32Array", attributes = Attribute.NOT_ENUMERABLE) public static Object getInt32Array(final Object self) { final Global global = Global.instanceFrom(self); @@ -502,6 +639,13 @@ return global.int32Array; } + + /** + * Setter for the Int32Array property. + * + * @param self self reference + * @param value value of the Int32Array property + */ @Setter(name = "Int32Array", attributes = Attribute.NOT_ENUMERABLE) public static void setInt32Array(final Object self, final Object value) { final Global global = Global.instanceFrom(self); @@ -510,7 +654,12 @@ private volatile Object int32Array; - /** TypedArray (uint32) */ + /** + * Getter of the Uint32Array property. + * + * @param self self reference + * @return the value of the Uint32Array property + */ @Getter(name = "Uint32Array", attributes = Attribute.NOT_ENUMERABLE) public static Object getUint32Array(final Object self) { final Global global = Global.instanceFrom(self); @@ -520,6 +669,13 @@ return global.uint32Array; } + + /** + * Setter of the Uint32Array property. + * + * @param self self reference + * @param value value of the Uint32Array property + */ @Setter(name = "Uint32Array", attributes = Attribute.NOT_ENUMERABLE) public static void setUint32Array(final Object self, final Object value) { final Global global = Global.instanceFrom(self); @@ -528,7 +684,12 @@ private volatile Object uint32Array; - /** TypedArray (float32) */ + /** + * Getter for the Float32Array property. + * + * @param self self reference + * @return the value of the Float32Array property + */ @Getter(name = "Float32Array", attributes = Attribute.NOT_ENUMERABLE) public static Object getFloat32Array(final Object self) { final Global global = Global.instanceFrom(self); @@ -538,6 +699,12 @@ return global.float32Array; } + /** + * Setter for the Float32Array property. + * + * @param self self reference + * @param value value of the Float32Array property + */ @Setter(name = "Float32Array", attributes = Attribute.NOT_ENUMERABLE) public static void setFloat32Array(final Object self, final Object value) { final Global global = Global.instanceFrom(self); @@ -546,7 +713,12 @@ private volatile Object float32Array; - /** TypedArray (float64) */ + /** + * Getter for the Float64Array property. + * + * @param self self reference + * @return the value of the Float64Array property + */ @Getter(name = "Float64Array", attributes = Attribute.NOT_ENUMERABLE) public static Object getFloat64Array(final Object self) { final Global global = Global.instanceFrom(self); @@ -556,6 +728,12 @@ return global.float64Array; } + /** + * Setter for the Float64Array property. + * + * @param self self reference + * @param value value of the Float64Array property + */ @Setter(name = "Float64Array", attributes = Attribute.NOT_ENUMERABLE) public static void setFloat64Array(final Object self, final Object value) { final Global global = Global.instanceFrom(self); @@ -592,7 +770,12 @@ @Property(attributes = Attribute.NOT_ENUMERABLE) public volatile Object org; - /** Nashorn extension: Java access - global.javaImporter */ + /** + * Getter for the Nashorn extension: Java access - global.javaImporter. + * + * @param self self reference + * @return the value of the JavaImporter property + */ @Getter(name = "JavaImporter", attributes = Attribute.NOT_ENUMERABLE) public static Object getJavaImporter(final Object self) { final Global global = Global.instanceFrom(self); @@ -602,6 +785,12 @@ return global.javaImporter; } + /** + * Setter for the Nashorn extension: Java access - global.javaImporter. + * + * @param self self reference + * @param value value of the JavaImporter property + */ @Setter(name = "JavaImporter", attributes = Attribute.NOT_ENUMERABLE) public static void setJavaImporter(final Object self, final Object value) { final Global global = Global.instanceFrom(self); @@ -610,7 +799,12 @@ private volatile Object javaImporter; - /** Nashorn extension: global.Java Object constructor. */ + /** + * Getter for the Nashorn extension: global.Java property. + * + * @param self self reference + * @return the value of the Java property + */ @Getter(name = "Java", attributes = Attribute.NOT_ENUMERABLE) public static Object getJavaApi(final Object self) { final Global global = Global.instanceFrom(self); @@ -620,6 +814,12 @@ return global.javaApi; } + /** + * Setter for the Nashorn extension: global.Java property. + * + * @param self self reference + * @param value value of the Java property + */ @Setter(name = "Java", attributes = Attribute.NOT_ENUMERABLE) public static void setJavaApi(final Object self, final Object value) { final Global global = Global.instanceFrom(self); @@ -2140,13 +2340,13 @@ @Override public void addBoundProperties(final ScriptObject source, final jdk.nashorn.internal.runtime.Property[] properties) { PropertyMap ownMap = getMap(); - LexicalScope lexicalScope = null; + LexicalScope lexScope = null; PropertyMap lexicalMap = null; boolean hasLexicalDefinitions = false; if (context.getEnv()._es6) { - lexicalScope = (LexicalScope) getLexicalScope(); - lexicalMap = lexicalScope.getMap(); + lexScope = (LexicalScope) getLexicalScope(); + lexicalMap = lexScope.getMap(); for (final jdk.nashorn.internal.runtime.Property property : properties) { if (property.isLexicalBinding()) { @@ -2166,8 +2366,8 @@ for (final jdk.nashorn.internal.runtime.Property property : properties) { if (property.isLexicalBinding()) { - assert lexicalScope != null; - lexicalMap = lexicalScope.addBoundProperty(lexicalMap, source, property); + assert lexScope != null; + lexicalMap = lexScope.addBoundProperty(lexicalMap, source, property); if (ownMap.findProperty(property.getKey()) != null) { // If property exists in the global object invalidate any global constant call sites. @@ -2181,7 +2381,8 @@ setMap(ownMap); if (hasLexicalDefinitions) { - lexicalScope.setMap(lexicalMap); + assert lexScope != null; + lexScope.setMap(lexicalMap); invalidateLexicalSwitchPoint(); } }
--- a/src/jdk/nashorn/internal/objects/NativeJava.java Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/objects/NativeJava.java Wed Jun 03 20:30:20 2015 -0700 @@ -33,10 +33,10 @@ import java.util.Collection; import java.util.Deque; import java.util.List; +import java.util.Queue; import jdk.internal.dynalink.beans.StaticClass; import jdk.internal.dynalink.support.TypeUtilities; import jdk.nashorn.api.scripting.JSObject; -import jdk.nashorn.api.scripting.ScriptUtils; import jdk.nashorn.internal.objects.annotations.Attribute; import jdk.nashorn.internal.objects.annotations.Function; import jdk.nashorn.internal.objects.annotations.ScriptClass; @@ -339,7 +339,8 @@ /** * Given a script object and a Java type, converts the script object into the desired Java type. Currently it - * performs shallow creation of Java arrays, as well as wrapping of objects in Lists and Dequeues. Example: + * performs shallow creation of Java arrays, as well as wrapping of objects in Lists, Dequeues, Queues, + * and Collections. Example: * <pre> * var anArray = [1, "13", false] * var javaIntArray = Java.to(anArray, "int[]") @@ -353,9 +354,10 @@ * object to create. Can not be null. If undefined, a "default" conversion is presumed (allowing the argument to be * omitted). * @return a Java object whose value corresponds to the original script object's value. Specifically, for array - * target types, returns a Java array of the same type with contents converted to the array's component type. Does - * not recursively convert for multidimensional arrays. For {@link List} or {@link Deque}, returns a live wrapper - * around the object, see {@link ListAdapter} for details. Returns null if obj is null. + * target types, returns a Java array of the same type with contents converted to the array's component type. + * Converts recursively when the target type is multidimensional array. For {@link List}, {@link Deque}, + * {@link Queue}, or {@link Collection}, returns a live wrapper around the object, see {@link ListAdapter} for + * details. Returns null if obj is null. * @throws ClassNotFoundException if the class described by objType is not found */ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @@ -385,7 +387,7 @@ return JSType.toJavaArray(obj, targetClass.getComponentType()); } - if(targetClass == List.class || targetClass == Deque.class) { + if (targetClass == List.class || targetClass == Deque.class || targetClass == Queue.class || targetClass == Collection.class) { return ListAdapter.create(obj); }
--- a/src/jdk/nashorn/internal/objects/NativeObject.java Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/objects/NativeObject.java Wed Jun 03 20:30:20 2015 -0700 @@ -765,7 +765,7 @@ continue; } properties.add(AccessorProperty.create(methodName, Property.NOT_WRITABLE, getBoundBeanMethodGetter(source, - method), null)); + method), Lookup.EMPTY_SETTER)); } for(final String propertyName: propertyNames) { MethodHandle getter;
--- a/src/jdk/nashorn/internal/parser/Parser.java Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/parser/Parser.java Wed Jun 03 20:30:20 2015 -0700 @@ -607,7 +607,7 @@ * @return whether the ident can be used as L-value */ private static boolean checkIdentLValue(final IdentNode ident) { - return Token.descType(ident.getToken()).getKind() != TokenKind.KEYWORD; + return ident.tokenType().getKind() != TokenKind.KEYWORD; } /**
--- a/src/jdk/nashorn/internal/runtime/CodeInstaller.java Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/runtime/CodeInstaller.java Wed Jun 03 20:30:20 2015 -0700 @@ -86,7 +86,7 @@ * @param source the script source * @param mainClassName the main class name * @param classBytes map of class names to class bytes - * @param initializers compilation id -> FunctionInitializer map + * @param initializers compilation id -> FunctionInitializer map * @param constants constants array * @param compilationId compilation id */
--- a/src/jdk/nashorn/internal/runtime/JSObjectListAdapter.java Thu May 28 20:55:21 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -package jdk.nashorn.internal.runtime; - -import jdk.nashorn.api.scripting.JSObject; - -/** - * A ListAdapter that can wraps a JSObject. - */ -public final class JSObjectListAdapter extends ListAdapter { - /** - * Creates a new list wrapper for the specified JSObject. - * @param obj JSOcript the object to wrap - */ - public JSObjectListAdapter(final JSObject obj) { - super(obj); - } - - @Override - public int size() { - return JSType.toInt32(((JSObject)obj).getMember("length")); - } - - @Override - protected Object getAt(final int index) { - return ((JSObject)obj).getSlot(index); - } - - @Override - protected void setAt(final int index, final Object element) { - ((JSObject)obj).setSlot(index, element); - } -}
--- a/src/jdk/nashorn/internal/runtime/JSType.java Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/runtime/JSType.java Wed Jun 03 20:30:20 2015 -0700 @@ -34,7 +34,6 @@ import java.lang.reflect.Array; import java.util.Arrays; import java.util.Collections; -import java.util.Deque; import java.util.List; import jdk.internal.dynalink.beans.StaticClass; import jdk.nashorn.api.scripting.AbstractJSObject; @@ -181,10 +180,10 @@ /** Div exact wrapper for potentially integer division that turns into float point */ public static final Call DIV_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "divExact", long.class, long.class, long.class, int.class); - /** Div zero wrapper for long division that handles (0/0) >>> 0 == 0 */ + /** Div zero wrapper for long division that handles (0/0) >>> 0 == 0 */ public static final Call DIV_ZERO_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "divZero", long.class, long.class, long.class); - /** Mod zero wrapper for long division that handles (0%0) >>> 0 == 0 */ + /** Mod zero wrapper for long division that handles (0%0) >>> 0 == 0 */ public static final Call REM_ZERO_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "remZero", long.class, long.class, long.class); /** Mod exact wrapper for potentially integer remainders that turns into float point */ @@ -202,12 +201,6 @@ /** Method handle to convert a JS Object to a Java array. */ public static final Call TO_JAVA_ARRAY = staticCall(JSTYPE_LOOKUP, JSType.class, "toJavaArray", Object.class, Object.class, Class.class); - /** Method handle to convert a JS Object to a Java List. */ - public static final Call TO_JAVA_LIST = staticCall(JSTYPE_LOOKUP, JSType.class, "toJavaList", List.class, Object.class); - - /** Method handle to convert a JS Object to a Java deque. */ - public static final Call TO_JAVA_DEQUE = staticCall(JSTYPE_LOOKUP, JSType.class, "toJavaDeque", Deque.class, Object.class); - /** Method handle for void returns. */ public static final Call VOID_RETURN = staticCall(JSTYPE_LOOKUP, JSType.class, "voidReturn", void.class); @@ -1352,24 +1345,6 @@ } /** - * Converts a JavaScript object to a Java List. See {@link ListAdapter} for details. - * @param obj the object to convert. Can be any array-like object. - * @return a List that is live-backed by the JavaScript object. - */ - public static List<?> toJavaList(final Object obj) { - return ListAdapter.create(obj); - } - - /** - * Converts a JavaScript object to a Java Deque. See {@link ListAdapter} for details. - * @param obj the object to convert. Can be any array-like object. - * @return a Deque that is live-backed by the JavaScript object. - */ - public static Deque<?> toJavaDeque(final Object obj) { - return ListAdapter.create(obj); - } - - /** * Check if an object is null or undefined * * @param obj object to check
--- a/src/jdk/nashorn/internal/runtime/ListAdapter.java Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/runtime/ListAdapter.java Wed Jun 03 20:30:20 2015 -0700 @@ -25,17 +25,18 @@ package jdk.nashorn.internal.runtime; +import java.lang.invoke.MethodHandle; import java.util.AbstractList; import java.util.Deque; import java.util.Iterator; import java.util.ListIterator; import java.util.NoSuchElementException; +import java.util.Objects; import java.util.RandomAccess; import java.util.concurrent.Callable; import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.api.scripting.ScriptObjectMirror; import jdk.nashorn.internal.runtime.linker.Bootstrap; -import jdk.nashorn.internal.runtime.linker.InvokeByName; /** * An adapter that can wrap any ECMAScript Array-like object (that adheres to the array rules for the property @@ -50,81 +51,56 @@ * operations respectively, while {@link #addLast(Object)} and {@link #removeLast()} will translate to {@code push} and * {@code pop}. */ -public abstract class ListAdapter extends AbstractList<Object> implements RandomAccess, Deque<Object> { - // These add to the back and front of the list - private static final Object PUSH = new Object(); - private static InvokeByName getPUSH() { - return Context.getGlobal().getInvokeByName(PUSH, - new Callable<InvokeByName>() { - @Override - public InvokeByName call() { - return new InvokeByName("push", Object.class, void.class, Object.class); - } - }); +public final class ListAdapter extends AbstractList<Object> implements RandomAccess, Deque<Object> { + // Invoker creator for methods that add to the start or end of the list: PUSH and UNSHIFT. Takes fn, this, and value, returns void. + private static final Callable<MethodHandle> ADD_INVOKER_CREATOR = invokerCreator(void.class, Object.class, JSObject.class, Object.class); + + // PUSH adds to the end of the list + private static final Object PUSH = new Object(); + private static MethodHandle getPushInvoker() { + return getDynamicInvoker(PUSH, ADD_INVOKER_CREATOR); } + // UNSHIFT adds to the start of the list private static final Object UNSHIFT = new Object(); - private static InvokeByName getUNSHIFT() { - return Context.getGlobal().getInvokeByName(UNSHIFT, - new Callable<InvokeByName>() { - @Override - public InvokeByName call() { - return new InvokeByName("unshift", Object.class, void.class, Object.class); - } - }); + private static MethodHandle getUnshiftInvoker() { + return getDynamicInvoker(UNSHIFT, ADD_INVOKER_CREATOR); } - // These remove from the back and front of the list + // Invoker creator for methods that remove from the tail or head of the list: POP and SHIFT. Takes fn, this, returns Object. + private static final Callable<MethodHandle> REMOVE_INVOKER_CREATOR = invokerCreator(Object.class, Object.class, JSObject.class); + + // POP removes from the to the end of the list private static final Object POP = new Object(); - private static InvokeByName getPOP() { - return Context.getGlobal().getInvokeByName(POP, - new Callable<InvokeByName>() { - @Override - public InvokeByName call() { - return new InvokeByName("pop", Object.class, Object.class); - } - }); + private static MethodHandle getPopInvoker() { + return getDynamicInvoker(POP, REMOVE_INVOKER_CREATOR); } + // SHIFT removes from the to the start of the list private static final Object SHIFT = new Object(); - private static InvokeByName getSHIFT() { - return Context.getGlobal().getInvokeByName(SHIFT, - new Callable<InvokeByName>() { - @Override - public InvokeByName call() { - return new InvokeByName("shift", Object.class, Object.class); - } - }); + private static MethodHandle getShiftInvoker() { + return getDynamicInvoker(SHIFT, REMOVE_INVOKER_CREATOR); } - // These insert and remove in the middle of the list + // SPLICE can be used to add a value in the middle of the list. private static final Object SPLICE_ADD = new Object(); - private static InvokeByName getSPLICE_ADD() { - return Context.getGlobal().getInvokeByName(SPLICE_ADD, - new Callable<InvokeByName>() { - @Override - public InvokeByName call() { - return new InvokeByName("splice", Object.class, void.class, int.class, int.class, Object.class); - } - }); + private static final Callable<MethodHandle> SPLICE_ADD_INVOKER_CREATOR = invokerCreator(void.class, Object.class, JSObject.class, int.class, int.class, Object.class); + private static MethodHandle getSpliceAddInvoker() { + return getDynamicInvoker(SPLICE_ADD, SPLICE_ADD_INVOKER_CREATOR); } + // SPLICE can also be used to remove values from the middle of the list. private static final Object SPLICE_REMOVE = new Object(); - private static InvokeByName getSPLICE_REMOVE() { - return Context.getGlobal().getInvokeByName(SPLICE_REMOVE, - new Callable<InvokeByName>() { - @Override - public InvokeByName call() { - return new InvokeByName("splice", Object.class, void.class, int.class, int.class); - } - }); + private static final Callable<MethodHandle> SPLICE_REMOVE_INVOKER_CREATOR = invokerCreator(void.class, Object.class, JSObject.class, int.class, int.class); + private static MethodHandle getSpliceRemoveInvoker() { + return getDynamicInvoker(SPLICE_REMOVE, SPLICE_REMOVE_INVOKER_CREATOR); } /** wrapped object */ - protected final Object obj; + protected final JSObject obj; // allow subclasses only in this package - ListAdapter(final Object obj) { + ListAdapter(final JSObject obj) { this.obj = obj; } @@ -135,14 +111,16 @@ * @return A ListAdapter wrapper object */ public static ListAdapter create(final Object obj) { + return new ListAdapter(getJSObject(obj)); + } + + private static JSObject getJSObject(final Object obj) { if (obj instanceof ScriptObject) { - final Object mirror = ScriptObjectMirror.wrap(obj, Context.getGlobal()); - return new JSObjectListAdapter((JSObject)mirror); + return (JSObject)ScriptObjectMirror.wrap(obj, Context.getGlobal()); } else if (obj instanceof JSObject) { - return new JSObjectListAdapter((JSObject)obj); - } else { - throw new IllegalArgumentException("ScriptObject or JSObject expected"); + return (JSObject)obj; } + throw new IllegalArgumentException("ScriptObject or JSObject expected"); } @Override @@ -151,28 +129,18 @@ return getAt(index); } - /** - * Get object at an index - * @param index index in list - * @return object - */ - protected abstract Object getAt(final int index); + private Object getAt(final int index) { + return obj.getSlot(index); + } @Override public Object set(final int index, final Object element) { checkRange(index); final Object prevValue = getAt(index); - setAt(index, element); + obj.setSlot(index, element); return prevValue; } - /** - * Set object at an index - * @param index index in list - * @param element element - */ - protected abstract void setAt(final int index, final Object element); - private void checkRange(final int index) { if(index < 0 || index >= size()) { throw invalidIndex(index); @@ -180,6 +148,11 @@ } @Override + public int size() { + return JSType.toInt32(obj.getMember("length")); + } + + @Override public final void push(final Object e) { addFirst(e); } @@ -193,10 +166,7 @@ @Override public final void addFirst(final Object e) { try { - final InvokeByName unshiftInvoker = getUNSHIFT(); - final Object fn = unshiftInvoker.getGetter().invokeExact(obj); - checkFunction(fn, unshiftInvoker); - unshiftInvoker.getInvoker().invokeExact(fn, obj, e); + getUnshiftInvoker().invokeExact(getFunction("unshift"), obj, e); } catch(RuntimeException | Error ex) { throw ex; } catch(final Throwable t) { @@ -207,10 +177,7 @@ @Override public final void addLast(final Object e) { try { - final InvokeByName pushInvoker = getPUSH(); - final Object fn = pushInvoker.getGetter().invokeExact(obj); - checkFunction(fn, pushInvoker); - pushInvoker.getInvoker().invokeExact(fn, obj, e); + getPushInvoker().invokeExact(getFunction("push"), obj, e); } catch(RuntimeException | Error ex) { throw ex; } catch(final Throwable t) { @@ -228,10 +195,7 @@ } else { final int size = size(); if(index < size) { - final InvokeByName spliceAddInvoker = getSPLICE_ADD(); - final Object fn = spliceAddInvoker.getGetter().invokeExact(obj); - checkFunction(fn, spliceAddInvoker); - spliceAddInvoker.getInvoker().invokeExact(fn, obj, index, 0, e); + getSpliceAddInvoker().invokeExact(obj.getMember("splice"), obj, index, 0, e); } else if(index == size) { addLast(e); } else { @@ -244,10 +208,12 @@ throw new RuntimeException(t); } } - private static void checkFunction(final Object fn, final InvokeByName invoke) { + private Object getFunction(final String name) { + final Object fn = obj.getMember(name); if(!(Bootstrap.isCallable(fn))) { - throw new UnsupportedOperationException("The script object doesn't have a function named " + invoke.getName()); + throw new UnsupportedOperationException("The script object doesn't have a function named " + name); } + return fn; } private static IndexOutOfBoundsException invalidIndex(final int index) { @@ -321,10 +287,7 @@ private Object invokeShift() { try { - final InvokeByName shiftInvoker = getSHIFT(); - final Object fn = shiftInvoker.getGetter().invokeExact(obj); - checkFunction(fn, shiftInvoker); - return shiftInvoker.getInvoker().invokeExact(fn, obj); + return getShiftInvoker().invokeExact(getFunction("shift"), obj); } catch(RuntimeException | Error ex) { throw ex; } catch(final Throwable t) { @@ -334,10 +297,7 @@ private Object invokePop() { try { - final InvokeByName popInvoker = getPOP(); - final Object fn = popInvoker.getGetter().invokeExact(obj); - checkFunction(fn, popInvoker); - return popInvoker.getInvoker().invokeExact(fn, obj); + return getPopInvoker().invokeExact(getFunction("pop"), obj); } catch(RuntimeException | Error ex) { throw ex; } catch(final Throwable t) { @@ -352,10 +312,7 @@ private void invokeSpliceRemove(final int fromIndex, final int count) { try { - final InvokeByName spliceRemoveInvoker = getSPLICE_REMOVE(); - final Object fn = spliceRemoveInvoker.getGetter().invokeExact(obj); - checkFunction(fn, spliceRemoveInvoker); - spliceRemoveInvoker.getInvoker().invokeExact(fn, obj, fromIndex, count); + getSpliceRemoveInvoker().invokeExact(getFunction("splice"), obj, fromIndex, count); } catch(RuntimeException | Error ex) { throw ex; } catch(final Throwable t) { @@ -443,12 +400,24 @@ private static boolean removeOccurrence(final Object o, final Iterator<Object> it) { while(it.hasNext()) { - final Object e = it.next(); - if(o == null ? e == null : o.equals(e)) { + if(Objects.equals(o, it.next())) { it.remove(); return true; } } return false; } + + private static Callable<MethodHandle> invokerCreator(final Class<?> rtype, final Class<?>... ptypes) { + return new Callable<MethodHandle>() { + @Override + public MethodHandle call() { + return Bootstrap.createDynamicInvoker("dyn:call", rtype, ptypes); + } + }; + } + + private static MethodHandle getDynamicInvoker(final Object key, final Callable<MethodHandle> creator) { + return Context.getGlobal().getDynamicInvoker(key, creator); + } }
--- a/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java Wed Jun 03 20:30:20 2015 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2015, 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 @@ -34,10 +34,13 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; +import java.io.StreamTokenizer; +import java.io.StringReader; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; +import java.util.ArrayList; +import java.util.List; import java.util.Map; -import java.util.StringTokenizer; /** * Global functions supported only in scripting mode. @@ -133,15 +136,8 @@ // Current global is need to fetch additional inputs and for additional results. final ScriptObject global = Context.getGlobal(); - // Break exec string into tokens. - final StringTokenizer tokenizer = new StringTokenizer(JSType.toString(string)); - final String[] cmdArray = new String[tokenizer.countTokens()]; - for (int i = 0; tokenizer.hasMoreTokens(); i++) { - cmdArray[i] = tokenizer.nextToken(); - } - // Set up initial process. - final ProcessBuilder processBuilder = new ProcessBuilder(cmdArray); + final ProcessBuilder processBuilder = new ProcessBuilder(tokenizeCommandLine(JSType.toString(string))); // Current ENV property state. final Object env = global.get(ENV_NAME); @@ -239,4 +235,43 @@ private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) { return MH.findStatic(MethodHandles.lookup(), ScriptingFunctions.class, name, MH.type(rtype, types)); } + + /** + * Break an exec string into tokens, honoring quoted arguments and escaped + * spaces. + * + * @param execString a {@link String} with the command line to execute. + * @return a {@link List} of {@link String}s representing the tokens that + * constitute the command line. + * @throws IOException in case {@link StreamTokenizer#nextToken()} raises it. + */ + public static List<String> tokenizeCommandLine(final String execString) throws IOException { + final StreamTokenizer tokenizer = new StreamTokenizer(new StringReader(execString)); + tokenizer.resetSyntax(); + tokenizer.wordChars(0, 255); + tokenizer.whitespaceChars(0, ' '); + tokenizer.commentChar('#'); + tokenizer.quoteChar('"'); + tokenizer.quoteChar('\''); + final List<String> cmdList = new ArrayList<>(); + final StringBuilder toAppend = new StringBuilder(); + while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) { + final String s = tokenizer.sval; + // The tokenizer understands about honoring quoted strings and recognizes + // them as one token that possibly contains multiple space-separated words. + // It does not recognize quoted spaces, though, and will split after the + // escaping \ character. This is handled here. + if (s.endsWith("\\")) { + // omit trailing \, append space instead + toAppend.append(s.substring(0, s.length() - 1)).append(' '); + } else { + cmdList.add(toAppend.append(s).toString()); + toAppend.setLength(0); + } + } + if (toAppend.length() != 0) { + cmdList.add(toAppend.toString()); + } + return cmdList; + } }
--- a/src/jdk/nashorn/internal/runtime/StoredScript.java Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/runtime/StoredScript.java Wed Jun 03 20:30:20 2015 -0700 @@ -58,7 +58,7 @@ * @param compilationId compilation id * @param mainClassName main class name * @param classBytes map of class names to class bytes - * @param initializers initializer map, id -> FunctionInitializer + * @param initializers initializer map, id -> FunctionInitializer * @param constants constants array */ public StoredScript(final int compilationId, final String mainClassName, final Map<String, byte[]> classBytes, final Map<Integer, FunctionInitializer> initializers, final Object[] constants) {
--- a/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java Wed Jun 03 20:30:20 2015 -0700 @@ -276,7 +276,7 @@ /** * Align an array size up to the nearest array chunk size * @param size size required - * @return size given, always >= size + * @return size given, always >= size */ protected final static int alignUp(final int size) { return size + CHUNK_SIZE - 1 & ~(CHUNK_SIZE - 1);
--- a/src/jdk/nashorn/internal/runtime/arrays/IntArrayData.java Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/runtime/arrays/IntArrayData.java Wed Jun 03 20:30:20 2015 -0700 @@ -182,14 +182,13 @@ @Override public ArrayData convert(final Class<?> type) { - if (type == Integer.class) { + if (type == Integer.class || type == Byte.class || type == Short.class) { return this; } else if (type == Long.class) { return convertToLong(); - } else if (type == Double.class) { + } else if (type == Double.class || type == Float.class) { return convertToDouble(); } else { - assert type == null || (!Number.class.isAssignableFrom(type) && !type.isPrimitive()); return convertToObject(); } }
--- a/src/jdk/nashorn/internal/runtime/arrays/LongArrayData.java Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/runtime/arrays/LongArrayData.java Wed Jun 03 20:30:20 2015 -0700 @@ -120,11 +120,11 @@ @Override public ContinuousArrayData convert(final Class<?> type) { - if (type == Integer.class || type == Long.class) { + if (type == Integer.class || type == Long.class || type == Byte.class || type == Short.class) { return this; } final int len = (int)length(); - if (type == Double.class) { + if (type == Double.class || type == Float.class) { return new NumberArrayData(toDoubleArray(), len); } return new ObjectArrayData(toObjectArray(false), len); @@ -171,7 +171,8 @@ @Override public ArrayData set(final int index, final Object value, final boolean strict) { - if (value instanceof Long || value instanceof Integer) { + if (value instanceof Long || value instanceof Integer || + value instanceof Byte || value instanceof Short) { return set(index, ((Number)value).longValue(), strict); } else if (value == ScriptRuntime.UNDEFINED) { return new UndefinedArrayFilter(this).set(index, value, strict);
--- a/src/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java Wed Jun 03 20:30:20 2015 -0700 @@ -29,6 +29,7 @@ import static jdk.nashorn.internal.lookup.Lookup.MH; import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; +import jdk.internal.dynalink.support.TypeUtilities; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.util.Arrays; @@ -104,9 +105,14 @@ return super.asArrayOfType(componentType); } + private static boolean canWiden(final Class<?> type) { + return TypeUtilities.isWrapperType(type) && + type != Boolean.class && type != Character.class; + } + @Override public ContinuousArrayData convert(final Class<?> type) { - if (type != Double.class && type != Integer.class && type != Long.class) { + if (! canWiden(type)) { final int len = (int)length(); return new ObjectArrayData(toObjectArray(false), len); } @@ -154,7 +160,7 @@ @Override public ArrayData set(final int index, final Object value, final boolean strict) { - if (value instanceof Double || value instanceof Integer || value instanceof Long) { + if (value instanceof Double || (value != null && canWiden(value.getClass()))) { return set(index, ((Number)value).doubleValue(), strict); } else if (value == UNDEFINED) { return new UndefinedArrayFilter(this).set(index, value, strict);
--- a/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java Wed Jun 03 20:30:20 2015 -0700 @@ -29,13 +29,15 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodHandles.Lookup; +import java.lang.invoke.MethodType; import java.lang.reflect.Modifier; import java.security.AccessController; import java.security.PrivilegedAction; +import java.util.Collection; import java.util.Deque; import java.util.List; import java.util.Map; +import java.util.Queue; import javax.script.Bindings; import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.linker.ConversionComparator; @@ -47,11 +49,13 @@ import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker; import jdk.internal.dynalink.support.Guards; import jdk.internal.dynalink.support.LinkerServicesImpl; +import jdk.internal.dynalink.support.Lookup; import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.api.scripting.ScriptObjectMirror; import jdk.nashorn.api.scripting.ScriptUtils; import jdk.nashorn.internal.objects.NativeArray; import jdk.nashorn.internal.runtime.JSType; +import jdk.nashorn.internal.runtime.ListAdapter; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.Undefined; @@ -167,7 +171,7 @@ return null; } - private static Lookup getCurrentLookup() { + private static java.lang.invoke.MethodHandles.Lookup getCurrentLookup() { final LinkRequest currentRequest = AccessController.doPrivileged(new PrivilegedAction<LinkRequest>() { @Override public LinkRequest run() { @@ -179,12 +183,12 @@ /** * Returns a guarded invocation that converts from a source type that is NativeArray to a Java array or List or - * Deque type. + * Queue or Deque or Collection type. * @param sourceType the source type (presumably NativeArray a superclass of it) - * @param targetType the target type (presumably an array type, or List or Deque) + * @param targetType the target type (presumably an array type, or List or Queue, or Deque, or Collection) * @return a guarded invocation that converts from the source type to the target type. null is returned if * either the source type is neither NativeArray, nor a superclass of it, or if the target type is not an array - * type, List, or Deque. + * type, List, Queue, Deque, or Collection. */ private static GuardedInvocation getArrayConverter(final Class<?> sourceType, final Class<?> targetType) { final boolean isSourceTypeNativeArray = sourceType == NativeArray.class; @@ -195,12 +199,14 @@ final MethodHandle guard = isSourceTypeGeneric ? IS_NATIVE_ARRAY : null; if(targetType.isArray()) { return new GuardedInvocation(ARRAY_CONVERTERS.get(targetType), guard); - } - if(targetType == List.class) { - return new GuardedInvocation(JSType.TO_JAVA_LIST.methodHandle(), guard); - } - if(targetType == Deque.class) { - return new GuardedInvocation(JSType.TO_JAVA_DEQUE.methodHandle(), guard); + } else if(targetType == List.class) { + return new GuardedInvocation(TO_LIST, guard); + } else if(targetType == Deque.class) { + return new GuardedInvocation(TO_DEQUE, guard); + } else if(targetType == Queue.class) { + return new GuardedInvocation(TO_QUEUE, guard); + } else if(targetType == Collection.class) { + return new GuardedInvocation(TO_COLLECTION, guard); } } return null; @@ -216,10 +222,11 @@ // Could've also used (targetType.isAssignableFrom(ScriptObjectMirror.class) && targetType != Object.class) but // it's probably better to explicitly spell out the supported target types if (targetType == Map.class || targetType == Bindings.class || targetType == JSObject.class || targetType == ScriptObjectMirror.class) { - if(ScriptObject.class.isAssignableFrom(sourceType)) { + if (ScriptObject.class.isAssignableFrom(sourceType)) { return new GuardedInvocation(CREATE_MIRROR); + } else if (sourceType.isAssignableFrom(ScriptObject.class) || sourceType.isInterface()) { + return new GuardedInvocation(CREATE_MIRROR, IS_SCRIPT_OBJECT); } - return new GuardedInvocation(CREATE_MIRROR, IS_SCRIPT_OBJECT); } return null; } @@ -285,6 +292,23 @@ private static final MethodHandle IS_NASHORN_OR_UNDEFINED_TYPE = findOwnMH("isNashornTypeOrUndefined", Boolean.TYPE, Object.class); private static final MethodHandle CREATE_MIRROR = findOwnMH("createMirror", Object.class, Object.class); + private static final MethodHandle TO_COLLECTION; + private static final MethodHandle TO_DEQUE; + private static final MethodHandle TO_LIST; + private static final MethodHandle TO_QUEUE; + static { + final MethodHandle listAdapterCreate = new Lookup(MethodHandles.lookup()).findStatic( + ListAdapter.class, "create", MethodType.methodType(ListAdapter.class, Object.class)); + TO_COLLECTION = asReturning(listAdapterCreate, Collection.class); + TO_DEQUE = asReturning(listAdapterCreate, Deque.class); + TO_LIST = asReturning(listAdapterCreate, List.class); + TO_QUEUE = asReturning(listAdapterCreate, Queue.class); + } + + private static MethodHandle asReturning(final MethodHandle mh, final Class<?> nrtype) { + return mh.asType(mh.type().changeReturnType(nrtype)); + } + @SuppressWarnings("unused") private static boolean isNashornTypeOrUndefined(final Object obj) { return obj instanceof ScriptObject || obj instanceof Undefined;
--- a/src/jdk/nashorn/internal/runtime/options/Options.java Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/runtime/options/Options.java Wed Jun 03 20:30:20 2015 -0700 @@ -424,9 +424,17 @@ public void process(final String[] args) { final LinkedList<String> argList = new LinkedList<>(); addSystemProperties(NASHORN_ARGS_PREPEND_PROPERTY, argList); + processArgList(argList); + assert argList.isEmpty(); Collections.addAll(argList, args); + processArgList(argList); + assert argList.isEmpty(); addSystemProperties(NASHORN_ARGS_PROPERTY, argList); + processArgList(argList); + assert argList.isEmpty(); + } + private void processArgList(final LinkedList<String> argList) { while (!argList.isEmpty()) { final String arg = argList.remove(0);
--- a/src/jdk/nashorn/internal/runtime/resources/Messages.properties Thu May 28 20:55:21 2015 -0700 +++ b/src/jdk/nashorn/internal/runtime/resources/Messages.properties Wed Jun 03 20:30:20 2015 -0700 @@ -121,7 +121,7 @@ type.error.cannot.get.default.number=Cannot get default number value type.error.cant.apply.with.to.null=Cannot apply "with" to null type.error.cant.apply.with.to.undefined=Cannot apply "with" to undefined -type.error.cant.apply.with.to.non.scriptobject=Cannot apply "with" to non script object +type.error.cant.apply.with.to.non.scriptobject=Cannot apply "with" to non script object. Consider using "with(Object.bindProperties('{'}, nonScriptObject))". type.error.in.with.non.object=Right hand side of "in" cannot be non-Object, found {0} type.error.prototype.not.an.object="prototype" of {0} is not an Object, it is {1} type.error.cant.load.script=Cannot load script from {0}
--- a/test/script/basic/8024180/with_java_object.js.EXPECTED Thu May 28 20:55:21 2015 -0700 +++ b/test/script/basic/8024180/with_java_object.js.EXPECTED Wed Jun 03 20:30:20 2015 -0700 @@ -1,1 +1,1 @@ -TypeError: Cannot apply "with" to non script object +TypeError: Cannot apply "with" to non script object. Consider using "with(Object.bindProperties({}, nonScriptObject))".
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8007456.js Wed Jun 03 20:30:20 2015 -0700 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2015 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-8007456: Nashorn test framework argument does not handle quoted strings + * + * @test + * @argument "hello world" + * @argument "This has spaces" + * @run + */ + +print(arguments.length); +print(arguments[0]); +print(arguments[1]);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8007456.js.EXPECTED Wed Jun 03 20:30:20 2015 -0700 @@ -0,0 +1,3 @@ +2 +hello world +This has spaces
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8071928.js Wed Jun 03 20:30:20 2015 -0700 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2015, 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-8071928: Instance properties with getters returning wrong values + * + * @test + * @run + */ + + +var types = {}; + +function Type() {} + +Type.prototype.getName = function() { + return this._name; +}; + +function defineType(init) { + return Object.create(Type.prototype, { + _name: { get: function() { return init.name; } } + }); +} + +types.A = defineType({ name: 'A' }); +types.B = defineType({ name: 'B' }); +types.C = defineType({ name: 'C' }); +types.D = defineType({ name: 'D' }); + +var keys = Object.keys(types); +for (var i = 0; i < keys.length; i++) { + var t = types[keys[i]]; + if (t.getName() != keys[i]) { + throw 'wrong name for ' + keys[i] + ': ' + t.getName(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8073846.js Wed Jun 03 20:30:20 2015 -0700 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2015, 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-8073846: Javascript for-in loop returned extra keys + * + * @test + * @run + */ + +var obj = {}; + +var list = [ + '2100000', + '420000', + '430000' +]; + +for (var i = 0; i < list.length; i++) { + if (obj[list[i]]) print("duplicate: " + list[i]); + obj[list[i]] = 'obj' + list[i] +} + +var count = 0; +for (var a in obj) { + count++; + if ('obj' + a !== obj[a]) { + throw 'wrong key or value: ' + a + ', ' + obj[a]; + } +} + +if (count !== 3) { + throw 'wrong entry count: ' + count; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8079145.js Wed Jun 03 20:30:20 2015 -0700 @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2015 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-8079145: jdk.nashorn.internal.runtime.arrays.IntArrayData.convert assertion + * + * @test + * @fork + * @option -Dnashorn.debug=true + * @run + */ + +var Byte = java.lang.Byte; +var Short = java.lang.Short; +var Integer = java.lang.Integer; +var Long = java.lang.Long; +var Float = java.lang.Float; +var Double = java.lang.Double; +var Character = java.lang.Character; + +function checkWiden(arr, value, name) { + switch (typeof value) { + case 'object': + case 'undefined': + print(name + ": check widen for " + value); + break; + default: + print(name + ": check widen for " + value + + " [" + Debug.getClass(value) + "]"); + } + + arr[0] = value; +} + +function checkIntWiden(value) { + checkWiden([34], value, "int array"); +} + +function checkLongWiden(value) { + checkWiden([Integer.MAX_VALUE + 1], value, "long array"); +} + +function checkNumberWiden(value) { + checkWiden([Math.PI], value, "number array"); +} + +function checkObjectWiden(value) { + checkWiden([null], value, "object array"); +} + +var values = [{}, null, undefined, false, true, new Byte(34), + new Integer(344454), new Long(454545), new Long(Integer.MAX_VALUE + 1), + new Float(34.3), new Double(Math.PI), new Character('s')]; + +for each (var v in values) { + checkIntWiden(v); +} + +for each (var v in values) { + checkLongWiden(v); +} + +for each (var v in values) { + checkNumberWiden(v); +} + +for each (var v in values) { + checkObjectWiden(v); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8079145.js.EXPECTED Wed Jun 03 20:30:20 2015 -0700 @@ -0,0 +1,48 @@ +int array: check widen for [object Object] +int array: check widen for null +int array: check widen for undefined +int array: check widen for false [class java.lang.Boolean] +int array: check widen for true [class java.lang.Boolean] +int array: check widen for 34 [class java.lang.Byte] +int array: check widen for 344454 [class java.lang.Integer] +int array: check widen for 454545 [class java.lang.Long] +int array: check widen for 2147483648 [class java.lang.Long] +int array: check widen for 34.29999923706055 [class java.lang.Float] +int array: check widen for 3.141592653589793 [class java.lang.Double] +int array: check widen for s +long array: check widen for [object Object] +long array: check widen for null +long array: check widen for undefined +long array: check widen for false [class java.lang.Boolean] +long array: check widen for true [class java.lang.Boolean] +long array: check widen for 34 [class java.lang.Byte] +long array: check widen for 344454 [class java.lang.Integer] +long array: check widen for 454545 [class java.lang.Long] +long array: check widen for 2147483648 [class java.lang.Long] +long array: check widen for 34.29999923706055 [class java.lang.Float] +long array: check widen for 3.141592653589793 [class java.lang.Double] +long array: check widen for s +number array: check widen for [object Object] +number array: check widen for null +number array: check widen for undefined +number array: check widen for false [class java.lang.Boolean] +number array: check widen for true [class java.lang.Boolean] +number array: check widen for 34 [class java.lang.Byte] +number array: check widen for 344454 [class java.lang.Integer] +number array: check widen for 454545 [class java.lang.Long] +number array: check widen for 2147483648 [class java.lang.Long] +number array: check widen for 34.29999923706055 [class java.lang.Float] +number array: check widen for 3.141592653589793 [class java.lang.Double] +number array: check widen for s +object array: check widen for [object Object] +object array: check widen for null +object array: check widen for undefined +object array: check widen for false [class java.lang.Boolean] +object array: check widen for true [class java.lang.Boolean] +object array: check widen for 34 [class java.lang.Byte] +object array: check widen for 344454 [class java.lang.Integer] +object array: check widen for 454545 [class java.lang.Long] +object array: check widen for 2147483648 [class java.lang.Long] +object array: check widen for 34.29999923706055 [class java.lang.Float] +object array: check widen for 3.141592653589793 [class java.lang.Double] +object array: check widen for s
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8079424.js Wed Jun 03 20:30:20 2015 -0700 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2015 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-8079424: code generator for discarded boolean logical operation has an extra pop + * + * @test + * @run + */ + +// If the compiler manages to compile all of these, the test passes. +void (true && true); +void (true && false); +void (false && true); +void (false && false); + +void (true || true); +void (true || false); +void (false || true); +void (false || false); + +void (1 && 1); +void (1 && 0); +void (0 && 1); +void (0 && 0); + +void (1 || 1); +void (1 || 0); +void (0 || 1); +void (0 || 0);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8080848.js Wed Jun 03 20:30:20 2015 -0700 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2015 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-8080848: delete of bound Java method property results in crash + * + * @test + * @run + */ + +var obj = Object.bindProperties({}, new java.io.File(".")); + +delete obj.wait; + +if (typeof obj.wait != 'undefined') { + throw new Error("obj.wait was not deleted"); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8081156.js Wed Jun 03 20:30:20 2015 -0700 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2015 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-8081156: jjs "nashorn.args" system property is not effective when script arguments are passed + * + * @test + * @fork + * @option -Dnashorn.args=-strict + * @argument foo + * @argument bar + * @run + */ + +try { + x = 14; + throw new Error("should have thrown ReferenceError"); +} catch (e) { + if (! (e instanceof ReferenceError)) { + throw e; + } +} + +Assert.assertTrue(arguments.length == 2); +Assert.assertTrue(arguments[0] == "foo"); +Assert.assertTrue(arguments[1] == "bar");
--- a/test/script/nosecurity/JDK-8050964.js Thu May 28 20:55:21 2015 -0700 +++ b/test/script/nosecurity/JDK-8050964.js Wed Jun 03 20:30:20 2015 -0700 @@ -47,7 +47,7 @@ } var javahome = System.getProperty("java.home"); -var jdepsPath = javahome + "/../bin/jdeps".replaceAll(/\//g, File.separater); +var jdepsPath = javahome + "/../bin/jdeps".replace(/\//g, File.separator); // run jdep on nashorn.jar - only summary but print profile info $ENV.PWD=System.getProperty("user.dir") // to avoid RE on Cygwin
--- a/test/script/nosecurity/JDK-8055034.js Thu May 28 20:55:21 2015 -0700 +++ b/test/script/nosecurity/JDK-8055034.js Wed Jun 03 20:30:20 2015 -0700 @@ -48,7 +48,7 @@ // we want to use nashorn.jar passed and not the one that comes with JRE var jjsCmd = javahome + "/../bin/jjs"; jjsCmd += " -J-Djava.ext.dirs=" + nashornJarDir; -jjsCmd = jjsCmd.toString().replaceAll(/\//g, File.separater); +jjsCmd = jjsCmd.toString().replace(/\//g, File.separator); $ENV.PWD=System.getProperty("user.dir") // to avoid RE on Cygwin $EXEC(jjsCmd, "var x = Object.create(null);\nx;\nprint('PASSED');\nexit(0)");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/internal/runtime/test/JDK_8078414_Test.java Wed Jun 03 20:30:20 2015 -0700 @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2015, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package jdk.nashorn.internal.runtime.test; + +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +import java.util.Map; +import javax.script.Bindings; +import jdk.nashorn.api.scripting.JSObject; +import jdk.nashorn.api.scripting.ScriptObjectMirror; +import jdk.nashorn.internal.objects.NativeArray; +import jdk.nashorn.internal.runtime.ScriptObject; +import jdk.nashorn.internal.runtime.linker.Bootstrap; +import org.testng.annotations.Test; + +/** + * @test + * @bug 8078414 + * @summary Test that arbitrary classes can't be converted to mirror's superclasses/interfaces. + * @run testng jdk.nashorn.internal.runtime.test.JDK_8078414_Test + */ +public class JDK_8078414_Test { + @Test + public void testCanNotConvertArbitraryClassToMirror() { + assertCanNotConvert(Double.class, Map.class); + assertCanNotConvert(Double.class, Bindings.class); + assertCanNotConvert(Double.class, JSObject.class); + assertCanNotConvert(Double.class, ScriptObjectMirror.class); + } + + @Test + public void testCanConvertObjectToMirror() { + assertCanConvertToMirror(Object.class); + } + + @Test + public void testCanConvertScriptObjectToMirror() { + assertCanConvertToMirror(ScriptObject.class); + } + + @Test + public void testCanConvertScriptObjectSubclassToMirror() { + assertCanConvertToMirror(NativeArray.class); + } + + @Test + public void testCanConvertArbitraryInterfaceToMirror() { + // We allow arbitrary interface classes, depending on what implements them, to end up being + // convertible to ScriptObjectMirror, as an implementation can theoretically pass an + // "instanceof ScriptObject" guard. + assertCanConvertToMirror(TestInterface.class); + } + + public static interface TestInterface { + } + + private static boolean canConvert(final Class<?> from, final Class<?> to) { + return Bootstrap.getLinkerServices().canConvert(from, to); + } + + private static void assertCanConvert(final Class<?> from, final Class<?> to) { + assertTrue(canConvert(from, to)); + } + + private static void assertCanNotConvert(final Class<?> from, final Class<?> to) { + assertFalse(canConvert(from, to)); + } + + private static void assertCanConvertToMirror(final Class<?> from) { + assertCanConvert(from, Map.class); + assertCanConvert(from, Bindings.class); + assertCanConvert(from, JSObject.class); + assertCanConvert(from, ScriptObjectMirror.class); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/internal/runtime/test/JDK_8081015_Test.java Wed Jun 03 20:30:20 2015 -0700 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2015, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package jdk.nashorn.internal.runtime.test; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; + +import java.util.Collection; +import java.util.Queue; +import javax.script.ScriptEngine; +import javax.script.ScriptException; +import jdk.nashorn.api.scripting.NashornScriptEngineFactory; +import jdk.nashorn.test.models.JDK_8081015_TestModel; +import org.testng.annotations.Test; + +/** + * @bug 8081015 + * @summary Test that native arrays get converted to {@link Queue} and {@link Collection}. + */ +@SuppressWarnings("javadoc") +public class JDK_8081015_Test { + @Test + public void testConvertToCollection() throws ScriptException { + test("receiveCollection"); + } + + @Test + public void testConvertToDeque() throws ScriptException { + test("receiveDeque"); + } + + @Test + public void testConvertToList() throws ScriptException { + test("receiveList"); + } + + @Test + public void testConvertToQueue() throws ScriptException { + test("receiveQueue"); + } + + private static void test(final String methodName) throws ScriptException { + final ScriptEngine engine = new NashornScriptEngineFactory().getScriptEngine(); + final JDK_8081015_TestModel model = new JDK_8081015_TestModel(); + engine.put("test", model); + + assertNull(model.getLastInvoked()); + engine.eval("test." + methodName + "([1, 2, 3.3, 'foo'])"); + assertEquals(model.getLastInvoked(), methodName ); + } +}
--- a/test/src/jdk/nashorn/internal/test/framework/TestFinder.java Thu May 28 20:55:21 2015 -0700 +++ b/test/src/jdk/nashorn/internal/test/framework/TestFinder.java Wed Jun 03 20:30:20 2015 -0700 @@ -22,7 +22,6 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ - package jdk.nashorn.internal.test.framework; import static jdk.nashorn.internal.test.framework.TestConfig.OPTIONS_CHECK_COMPILE_MSG; @@ -61,14 +60,15 @@ import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Scanner; import java.util.Set; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; +import jdk.nashorn.internal.runtime.ScriptingFunctions; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; @@ -78,28 +78,33 @@ */ @SuppressWarnings("javadoc") public final class TestFinder { - private TestFinder() {} + + private TestFinder() { + } interface TestFactory<T> { + // 'test' instance type is decided by the client. + T createTest(final String framework, final File testFile, final List<String> engineOptions, final Map<String, String> testOptions, final List<String> arguments); + // place to log messages from TestFinder + void log(String mg); } - // finds all tests from configuration and calls TestFactory to create 'test' instance for each script test found static <T> void findAllTests(final List<T> tests, final Set<String> orphans, final TestFactory<T> testFactory) throws Exception { final String framework = System.getProperty(TEST_JS_FRAMEWORK); final String testList = System.getProperty(TEST_JS_LIST); final String failedTestFileName = System.getProperty(TEST_FAILED_LIST_FILE); - if(failedTestFileName != null) { + if (failedTestFileName != null) { final File failedTestFile = new File(failedTestFileName); - if(failedTestFile.exists() && failedTestFile.length() > 0L) { - try(final BufferedReader r = new BufferedReader(new FileReader(failedTestFile))) { - for(;;) { + if (failedTestFile.exists() && failedTestFile.length() > 0L) { + try (final BufferedReader r = new BufferedReader(new FileReader(failedTestFile))) { + for (;;) { final String testFileName = r.readLine(); - if(testFileName == null) { + if (testFileName == null) { break; } handleOneTest(framework, new File(testFileName).toPath(), tests, orphans, testFactory); @@ -151,7 +156,7 @@ final Exception[] exceptions = new Exception[1]; final List<String> excludedActualTests = new ArrayList<>(); - if (! dir.toFile().isDirectory()) { + if (!dir.toFile().isDirectory()) { factory.log("WARNING: " + dir + " not found or not a directory"); } @@ -219,27 +224,28 @@ boolean explicitOptimistic = false; - try (Scanner scanner = new Scanner(testFile)) { - while (scanner.hasNext()) { - // TODO: Scan for /ref=file qualifiers, etc, to determine run - // behavior - String token = scanner.next(); - if (token.startsWith("/*")) { - inComment = true; - } else if (token.endsWith(("*/"))) { - inComment = false; - } else if (!inComment) { - continue; - } + String allContent = new String(Files.readAllBytes(testFile)); + Iterator<String> scanner = ScriptingFunctions.tokenizeCommandLine(allContent).iterator(); + while (scanner.hasNext()) { + // TODO: Scan for /ref=file qualifiers, etc, to determine run + // behavior + String token = scanner.next(); + if (token.startsWith("/*")) { + inComment = true; + } else if (token.endsWith(("*/"))) { + inComment = false; + } else if (!inComment) { + continue; + } - // remove whitespace and trailing semicolons, if any - // (trailing semicolons are found in some sputnik tests) - token = token.trim(); - final int semicolon = token.indexOf(';'); - if (semicolon > 0) { - token = token.substring(0, semicolon); - } - switch (token) { + // remove whitespace and trailing semicolons, if any + // (trailing semicolons are found in some sputnik tests) + token = token.trim(); + final int semicolon = token.indexOf(';'); + if (semicolon > 0) { + token = token.substring(0, semicolon); + } + switch (token) { case "@test": isTest = true; break; @@ -308,24 +314,21 @@ break; default: break; - } + } - // negative tests are expected to fail at runtime only - // for those tests that are expected to fail at compile time, - // add @test/compile-error - if (token.equals("@negative") || token.equals("@strict_mode_negative")) { - shouldRun = true; - runFailure = true; - } + // negative tests are expected to fail at runtime only + // for those tests that are expected to fail at compile time, + // add @test/compile-error + if (token.equals("@negative") || token.equals("@strict_mode_negative")) { + shouldRun = true; + runFailure = true; + } - if (token.equals("@strict_mode") || token.equals("@strict_mode_negative") || token.equals("@onlyStrict") || token.equals("@noStrict")) { - if (!strictModeEnabled()) { - return; - } + if (token.equals("@strict_mode") || token.equals("@strict_mode_negative") || token.equals("@onlyStrict") || token.equals("@noStrict")) { + if (!strictModeEnabled()) { + return; } } - } catch (final Exception ignored) { - return; } if (isTest) { @@ -369,8 +372,8 @@ private static final boolean OPTIMISTIC_OVERRIDE = true; /** - * Check if there is an optimistic override, that disables the default - * false optimistic types and sets them to true, for testing purposes + * Check if there is an optimistic override, that disables the default false + * optimistic types and sets them to true, for testing purposes * * @return true if optimistic type override has been set by test suite */ @@ -379,10 +382,9 @@ } /** - * Add an optimistic-types=true option to an argument list if this - * is set to override the default false. Add an optimistic-types=true - * options to an argument list if this is set to override the default - * true + * Add an optimistic-types=true option to an argument list if this is set to + * override the default false. Add an optimistic-types=true options to an + * argument list if this is set to override the default true * * @args new argument list array */ @@ -396,8 +398,8 @@ } /** - * Add an optimistic-types=true option to an argument list if this - * is set to override the default false + * Add an optimistic-types=true option to an argument list if this is set to + * override the default false * * @args argument list */ @@ -438,7 +440,7 @@ private static void loadExcludesFile(final String testExcludesFile, final Set<String> testExcludeSet) throws XPathExpressionException { final XPath xpath = XPathFactory.newInstance().newXPath(); - final NodeList testIds = (NodeList)xpath.evaluate("/excludeList/test/@id", new InputSource(testExcludesFile), XPathConstants.NODESET); + final NodeList testIds = (NodeList) xpath.evaluate("/excludeList/test/@id", new InputSource(testExcludesFile), XPathConstants.NODESET); for (int i = testIds.getLength() - 1; i >= 0; i--) { testExcludeSet.add(testIds.item(i).getNodeValue()); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/test/models/JDK_8081015_TestModel.java Wed Jun 03 20:30:20 2015 -0700 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2015, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package jdk.nashorn.test.models; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; + +import java.util.Collection; +import java.util.Deque; +import java.util.Iterator; +import java.util.List; +import java.util.Queue; + +@SuppressWarnings("javadoc") +public class JDK_8081015_TestModel { + private String lastInvoked; + + public void receiveCollection(final Collection<Object> c) { + lastInvoked = "receiveCollection"; + walkCollection(c); + } + + public void receiveDeque(final Deque<Object> d) { + lastInvoked = "receiveDeque"; + walkCollection(d); + } + + public void receiveList(final List<Object> l) { + lastInvoked = "receiveList"; + walkCollection(l); + } + + public void receiveQueue(final Queue<Object> q) { + lastInvoked = "receiveQueue"; + walkCollection(q); + } + + public String getLastInvoked() { + return lastInvoked; + } + + private static void walkCollection(final Collection<Object> c) { + final Iterator<Object> it = c.iterator(); + assertEquals(it.next(), Integer.valueOf(1)); + assertEquals(it.next(), Integer.valueOf(2)); + assertEquals(it.next(), Double.valueOf(3.3)); + assertEquals(it.next(), "foo"); + assertFalse(it.hasNext()); + } +}