diff --git a/nashorn/make/build.xml b/nashorn/make/build.xml
index d48765fefe4..7a9937f1f4c 100644
--- a/nashorn/make/build.xml
+++ b/nashorn/make/build.xml
@@ -93,7 +93,21 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/LinkedMap.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/LinkedMap.java
index 917bf099956..4e7187cefe7 100644
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/LinkedMap.java
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/LinkedMap.java
@@ -62,7 +62,7 @@ public class LinkedMap {
*/
static class Node {
private final Object key;
- private final Object value;
+ private volatile Object value;
private volatile boolean alive = true;
private volatile Node prev;
@@ -103,6 +103,14 @@ public class LinkedMap {
public Object getValue() {
return value;
}
+
+ /**
+ * Set the node's value
+ * @param value the new value
+ */
+ void setValue(final Object value) {
+ this.value = value;
+ }
}
/**
@@ -150,12 +158,14 @@ public class LinkedMap {
* @param value the value
*/
public void set(final Object key, final Object value) {
- final Node newNode = new Node(key, value);
- final Node oldNode = data.put(key, newNode);
- if (oldNode != null) {
- unlink(oldNode);
+ Node node = data.get(key);
+ if (node != null) {
+ node.setValue(value);
+ } else {
+ node = new Node(key, value);
+ data.put(key, node);
+ link(node);
}
- link(newNode);
}
/**
diff --git a/nashorn/test/script/basic/es6/JDK-8151809.js b/nashorn/test/script/basic/es6/JDK-8151809.js
new file mode 100644
index 00000000000..ac04d3ba402
--- /dev/null
+++ b/nashorn/test/script/basic/es6/JDK-8151809.js
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2016, 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-8151809: ES6 Map/Set insertion with existing keys changes iteration order
+ *
+ * @test
+ * @run
+ * @option --language=es6
+ */
+
+function assertSetIteratorResult(result, expectedDone, expectedValue) {
+ Assert.assertEquals(result.done, expectedDone);
+ Assert.assertEquals(result.value, expectedValue);
+}
+
+function assertMapIteratorResult(result, expectedDone, expectedKey, expectedValue) {
+ Assert.assertEquals(result.done, expectedDone);
+ if (expectedDone) {
+ Assert.assertEquals(result.value, undefined);
+ } else {
+ Assert.assertEquals(result.value[0], expectedKey);
+ Assert.assertEquals(result.value[1], expectedValue);
+ }
+}
+
+let set = new Set(["foo", "bar", "foo"]);
+let iter = set[Symbol.iterator]();
+assertSetIteratorResult(iter.next(), false, "foo");
+assertSetIteratorResult(iter.next(), false, "bar");
+assertSetIteratorResult(iter.next(), true);
+
+set.add ("foo");
+iter = set[Symbol.iterator]();
+assertSetIteratorResult(iter.next(), false, "foo", false);
+assertSetIteratorResult(iter.next(), false, "bar", false);
+assertSetIteratorResult(iter.next(), true);
+
+set.delete("foo");
+set.add ("foo");
+assertSetIteratorResult(iter.next(), true);
+iter = set[Symbol.iterator]();
+assertSetIteratorResult(iter.next(), false, "bar", false);
+assertSetIteratorResult(iter.next(), false, "foo", false);
+assertSetIteratorResult(iter.next(), true);
+
+
+let map = new Map([["foo", 1], ["bar", 2], ["foo", 3]]);
+iter = map[Symbol.iterator]();
+assertMapIteratorResult(iter.next(), false, "foo", 3);
+assertMapIteratorResult(iter.next(), false, "bar", 2);
+assertMapIteratorResult(iter.next(), true);
+
+
+map.set("foo", 4);
+iter = map[Symbol.iterator]();
+assertMapIteratorResult(iter.next(), false, "foo", 4);
+assertMapIteratorResult(iter.next(), false, "bar", 2);
+assertMapIteratorResult(iter.next(), true);
+
+map.delete("foo");
+map.set("foo", 5);
+assertMapIteratorResult(iter.next(), true);
+iter = map[Symbol.iterator]();
+assertMapIteratorResult(iter.next(), false, "bar", 2);
+assertMapIteratorResult(iter.next(), false, "foo", 5);
+assertMapIteratorResult(iter.next(), true);
diff --git a/nashorn/test/script/nosecurity/JDK-8144221.js b/nashorn/test/script/nosecurity/JDK-8144221.js
index 619332de032..6bdd7e6dd56 100644
--- a/nashorn/test/script/nosecurity/JDK-8144221.js
+++ b/nashorn/test/script/nosecurity/JDK-8144221.js
@@ -26,7 +26,7 @@
*
* @test
* @option -scripting
- * @run
+ * @runif os.not.windows.cmd
*/
// The test generates three different JavaScript source files. The first two
diff --git a/nashorn/test/script/nosecurity/JDK-8151291.js b/nashorn/test/script/nosecurity/JDK-8151291.js
index 15ae427913c..53d28845562 100644
--- a/nashorn/test/script/nosecurity/JDK-8151291.js
+++ b/nashorn/test/script/nosecurity/JDK-8151291.js
@@ -27,7 +27,7 @@
*
* @test
* @option -scripting
- * @run
+ * @runif os.not.windows.cmd
*/
$EXEC(["java", "-version"])
diff --git a/nashorn/test/script/nosecurity/JDK-util.js b/nashorn/test/script/nosecurity/JDK-util.js
new file mode 100644
index 00000000000..8db4ac2b331
--- /dev/null
+++ b/nashorn/test/script/nosecurity/JDK-util.js
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+/**
+ * This file contains utility functions used by other tests.
+ * @subtest
+ */
+
+var Files = Java.type('java.nio.file.Files'),
+ Paths = Java.type('java.nio.file.Paths'),
+ System = Java.type('java.lang.System')
+
+var File = java.io.File
+var windows = System.getProperty("os.name").startsWith("Windows")
+var winCyg = false
+
+var outPath = {
+ windows:0, //C:\dir
+ mixed:1 //C:/dir
+}
+
+if (windows) {
+ //Is there any better way to diffrentiate between cygwin/command prompt on windows
+ var term = System.getenv("TERM")
+ winCyg = term ? true:false
+}
+
+/**
+ * Returns which command is selected from PATH
+ * @param cmd name of the command searched from PATH
+ */
+function which(cmd) {
+ var path = System.getenv("PATH")
+ var st = new java.util.StringTokenizer(path, File.pathSeparator)
+ while (st.hasMoreTokens()) {
+ var file = new File(st.nextToken(), cmd)
+ if (file.exists()) {
+ return (file.getAbsolutePath())
+ }
+ }
+}
+
+/**
+ * Removes a given file
+ * @param pathname name of the file
+ */
+function rm(pathname) {
+ var Path = Paths.get(pathname)
+ if (!Files.deleteIfExists(Path))
+ print("File \"${pathname}\" doesn't exist")
+}
+
+
+
+/**
+ * Unix cygpath implementation
+ * Supports only two outputs,windows(C:\dir\) and mixed(C:/dir/)
+ */
+function cygpath(path,mode) {
+
+ var newpath = path
+ if(path.startsWith("/cygdrive/")){
+ var str = path.substring(10)
+ var index = str.indexOf('/',0)
+ var drv = str.substring(0,index)
+ var rstr = drv.toUpperCase() + ":"
+ newpath = str.replaceFirst(drv,rstr)
+ }
+ if (mode == outPath.windows)
+ return Paths.get(newpath).toString()
+ else {
+ newpath = newpath.replaceAll('\\\\','/')
+ return newpath
+ }
+
+}
+
+/**
+ * convert given path based on underlying shell programme runs on
+ */
+function toShellPath(path) {
+ if (windows) {
+ if (winCyg) {
+ return cygpath(path,outPath.mixed)
+ }else {
+ var path = cygpath(path,outPath.windows)
+ //convert '\' ->'\\',cmd shell expects this.
+ return path.replaceAll('\\\\','\\\\\\\\')
+ }
+ }else {
+ return path
+ }
+}
+
diff --git a/nashorn/test/script/nosecurity/jjs-common.js b/nashorn/test/script/nosecurity/jjs-common.js
index 3ea30843a84..68c296bb68c 100644
--- a/nashorn/test/script/nosecurity/jjs-common.js
+++ b/nashorn/test/script/nosecurity/jjs-common.js
@@ -26,15 +26,29 @@
* @subtest
* @summary test used by all other jjs-option* test cases
*/
-var javaHome = $ENV.JAVA_HOME,
- homeJjs = "${javaHome}/bin/jjs",
- altJjs = $EXEC('which jjs').trim(),
- homejavac = "${javaHome}/bin/javac",
- altjavac = $EXEC('which javac').trim()
-var Files = Java.type('java.nio.file.Files'),
- Paths = Java.type('java.nio.file.Paths'),
- System = Java.type('java.lang.System')
+load(__DIR__ + "JDK-util.js")
+
+var javaHome = System.getenv("JAVA_HOME"),
+ homeJjs = "${javaHome}" + "/bin/jjs",
+ altJjs = which('jjs'),
+ homejavac = "${javaHome}" + "/bin/javac",
+ altjavac = which('javac')
+
+if (windows) {
+ if (winCyg) {
+ //Files.exists() expects proper extension as it talks to windows filesystem even on cygwin
+ //make paths work on on underlying shells cygwin/cmd/linux.
+ homeJjs = toShellPath("${javaHome}" + "/bin/jjs.exe")
+ homejavac = toShellPath("${javaHome}" + "/bin/javac.exe")
+ }
+ else {
+ homeJjs = toShellPath("${javaHome}" + "\\bin\\jjs.exe")
+ homejavac = toShellPath("${javaHome}" + "\\bin\\javac.exe")
+ }
+ altJjs = which('jjs.exe')
+ altjavac = which('javac.exe')
+}
// Initialize default values for variables used in different functions
var func_cond_p = <