diff --git a/README b/README
index 242d6077b679095a476b829508f1985b5d7c042f..9cc6c72321338e8eb8907b429c52ac12ac775712 100644
--- a/README
+++ b/README
@@ -72,14 +72,11 @@ after which you can view the generated documentation at dist/javadoc/index.html.
- Running tests
Nashorn tests are TestNG based. Running tests requires downloading the
-TestNG library and placing its jar file into the lib subdirectory:
+TestNG library and placing its jar file into the test/lib subdirectory. This is
+done automatically when executing the "ant externals" command to get external
+test suites (see below).
- # download and install TestNG
- wget http://testng.org/testng-x.y.z.zip
- unzip testng-x.y.z.zip
- cp testng-x.y.z/testng-x.y.z.jar test/lib/testng.jar
-
-After that, you can run the tests using:
+Once TestNG is properly installed, you can run the tests using:
cd make
ant clean test
diff --git a/make/build.xml b/make/build.xml
index 38118a6bbc21a129c1f740cd3bd36d3e98392f9c..555c3456085a23293595acb2f5df80a758f2ae37 100644
--- a/make/build.xml
+++ b/make/build.xml
@@ -1,7 +1,7 @@
@@ -460,7 +460,7 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" {
-
+
@@ -490,7 +490,7 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" {
-
+
@@ -518,7 +518,7 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" {
-
+
@@ -537,7 +537,7 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" {
-
+
@@ -561,7 +561,7 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" {
-
+
@@ -580,7 +580,7 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" {
-
+
-
+
@@ -710,8 +710,8 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" {
-
-
+
+
@@ -721,12 +721,20 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" {
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
+
diff --git a/make/project.properties b/make/project.properties
index 89374b18a0f78ca0b550292793ab5fcf701374d1..d8264274877ed3e6691ff234eac4413007a38136 100644
--- a/make/project.properties
+++ b/make/project.properties
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2010, 2014, 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
@@ -77,8 +77,11 @@ fxshell.jar = ${dist.dir}/nashornfx.jar
# configuration for java flight recorder
run.test.jvmargs.jfr=-XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:FlightRecorderOptions=defaultrecording=true,disk=true,dumponexit=true,dumponexitpath=${build.dir},stackdepth=128
+# test library location
+test.lib=${basedir}${file.separator}test${file.separator}lib
+
# jars refererred
-file.reference.testng.jar=test/lib/testng.jar
+file.reference.testng.jar=${test.lib}${file.separator}testng.jar
# Set testng verbose level
# From TestNG docs: "the verbosity level (0 to 10 where 10 is most detailed)
@@ -237,9 +240,9 @@ testjfx-test-sys-prop.test.js.framework=\
-fx \
${test.script.dir}${file.separator}jfx.js
-file.reference.jemmyfx.jar=test${file.separator}lib${file.separator}JemmyFX.jar
-file.reference.jemmycore.jar=test${file.separator}lib${file.separator}JemmyCore.jar
-file.reference.jemmyawtinput.jar=test${file.separator}lib${file.separator}JemmyAWTInput.jar
+file.reference.jemmyfx.jar=${test.lib}${file.separator}JemmyFX.jar
+file.reference.jemmycore.jar=${test.lib}${file.separator}JemmyCore.jar
+file.reference.jemmyawtinput.jar=${test.lib}${file.separator}JemmyAWTInput.jar
file.reference.jfxrt.jar=${java.home}${file.separator}lib${file.separator}ext${file.separator}jfxrt.jar
testjfx.run.test.classpath=\
${file.reference.jemmyfx.jar}${path.separator}\
diff --git a/samples/autoimports.js b/samples/autoimports.js
new file mode 100644
index 0000000000000000000000000000000000000000..85683f54d773915cba8f60426d2f62afd9ae4427
--- /dev/null
+++ b/samples/autoimports.js
@@ -0,0 +1,163 @@
+# autoimports script requires -scripting mode
+
+/*
+ * 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.
+ */
+
+/*
+ * It is tedious to import Java classes used in a script. Sometimes it is easier
+ * use simple names of java classes and have a script auto import Java classes.
+ * You can load this script at the start of an interactive jjs session or at the
+ * start of your script. This script defines a __noSuchProperty__ hook to auto
+ * import Java classes as needed and when they are referred to for the first time
+ * in your script. You can also call the "autoimports" function to print script
+ * statements that you need to use in your script, i.e., have the function generate
+ * a script to import Java classes used by your script so far. After running your
+ * script, you can call autoimports to get the exact Java imports you need and replace
+ * the autoimports load with the generated import statements (to avoid costly init of
+ * the autoimports script).
+ */
+
+(function() {
+ var ArrayList = Java.type("java.util.ArrayList");
+ var HashMap = Java.type("java.util.HashMap");
+ var JarFile = Java.type("java.util.jar.JarFile");
+ var File = Java.type("java.io.File");
+ var Files = Java.type("java.nio.file.Files");
+ var FileSystems = Java.type("java.nio.file.FileSystems");
+ var System = Java.type("java.lang.System");
+ var URI = Java.type("java.net.URI");
+
+ // initialize a class to package map by iterating all
+ // classes available in the system by walking through "jrt fs"
+
+ var clsToPkg = new HashMap();
+
+ // locate rt.jar from sun.boot.class.path
+ function findRtJar() {
+ var paths = System.getProperty("sun.boot.class.path").split(File.pathSeparator);
+ for each (var p in paths) {
+ if (p.endsWith("rt.jar") && new File(p).exists()) {
+ return p;
+ }
+ }
+ }
+
+
+ function addToClsToPkg(c, p) {
+ if (clsToPkg.containsKey(c)) {
+ var val = clsToPkg.get(c);
+ if (val instanceof ArrayList) {
+ val.add(p);
+ } else {
+ var al = new ArrayList();
+ al.add(val);
+ al.add(p);
+ clsToPkg.put(c, al);
+ }
+ } else {
+ clsToPkg.put(c, p);
+ }
+ }
+
+ // handle collision and allow user to choose package
+ function getPkgOfCls(c) {
+ var val = clsToPkg.get(c);
+ if (val instanceof ArrayList) {
+ var count = 1;
+ print("Multiple matches for " + c + ", choose package:");
+ for each (var v in val) {
+ print(count + ". " + v);
+ count++;
+ }
+ var choice = parseInt(readLine());
+ if (isNaN(choice) || choice < 1 || choice > val.size()) {
+ print("invalid choice: " + choice);
+ return undefined;
+ }
+ return val.get(choice - 1);
+ } else {
+ return val;
+ }
+ }
+
+ var rtJar = findRtJar();
+ var stream = new JarFile(rtJar).stream();
+ try {
+ stream.forEach(
+ function(entry) {
+ var str = entry.name;
+ if (str.endsWith(".class")) {
+ if (str.startsWith("java") ||
+ str.startsWith("javax") ||
+ str.startsWith("org")) {
+ var lastIdx = str.lastIndexOf('/');
+ if (lastIdx != -1) {
+ var pkg = str.substring(0, lastIdx).replaceAll('/', '.');
+ var cls = str.substring(lastIdx + 1, str.lastIndexOf(".class"));
+ addToClsToPkg(cls, pkg);
+ }
+ }
+ }
+ });
+ } finally {
+ stream.close();
+ }
+
+ var imports = new ArrayList();
+ var global = this;
+ var oldNoSuchProp = global.__noSuchProperty__;
+ this.__noSuchProperty__ = function(name) {
+ 'use strict';
+
+ if (clsToPkg.containsKey(name)) {
+ var pkg = getPkgOfCls(name);
+ if (pkg) {
+ var clsName = pkg + "." + name;
+ imports.add("var " + name + " = Java.type('" + clsName + "');");
+ return global[name] = Java.type(clsName);
+ }
+ } else if (typeof oldNoSuchProp == 'function') {
+ return oldNoSuchProp.call(this, name);
+ }
+
+ if (typeof this == 'undefined') {
+ throw new ReferenceError(name);
+ } else {
+ return undefined;
+ }
+ }
+
+ this.autoimports = function() {
+ for each (var im in imports) {
+ print(im);
+ }
+ }
+})();
diff --git a/samples/dateconversion.js b/samples/dateconversion.js
new file mode 100644
index 0000000000000000000000000000000000000000..a8abda69115b64017bfa8adbd83d7e8ff2cd9f43
--- /dev/null
+++ b/samples/dateconversion.js
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+// Converting between #javascript Date and #java8 LocalDateTime with #nashorn
+
+// JavaScript Date with current time
+var d = new Date();
+print(d);
+
+// Java 8 java.time classes used
+var Instant = java.time.Instant;
+var LocalDateTime = java.time.LocalDateTime;
+var ZoneId = java.time.ZoneId;
+
+// Date.prototype.getTime
+
+// getTime() method returns the numeric value corresponding to the time
+// for the specified date according to universal time. The value returned
+// by the getTime() method is the number of milliseconds since 1 January 1970 00:00:00 UTC.
+// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTime
+
+// Java Instant.ofEpochMilli to convert time in milliseconds to Instant object
+// https://docs.oracle.com/javase/8/docs/api/java/time/Instant.html#ofEpochMilli-long-
+
+var instant = Instant.ofEpochMilli(d.getTime());
+
+// Instant to LocalDateTime using LocalDateTime.ofInstant
+// https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html#ofInstant-java.time.Instant-java.time.ZoneId-
+
+var ldt = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
+print(ldt);
+
+// converting a LocalDateTime to JavaScript Date
+// convert LocalDateTime to Instant first
+// https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html#atZone-java.time.ZoneId-
+
+var instant = ldt.atZone(ZoneId.systemDefault()).toInstant();
+
+// instant to to epoch milliseconds
+// https://docs.oracle.com/javase/8/docs/api/java/time/Instant.html#toEpochMilli--
+// and then to JavaScript Date from time in milliseconds
+// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date
+
+var d1 = new Date(instant.toEpochMilli());
+print(d1);
diff --git a/samples/exec.js b/samples/exec.js
new file mode 100644
index 0000000000000000000000000000000000000000..68581c3d7a29021f7ad91feb87ba31b2369e552f
--- /dev/null
+++ b/samples/exec.js
@@ -0,0 +1,50 @@
+# exec script requires -scripting mode
+
+/*
+ * 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.
+ */
+
+// The $EXEC builtin function can be used to run external commands:
+$EXEC("ls")
+$EXEC("ls -la")
+
+// It can also be given a string to use as stdin:
+$EXEC("cat", "Hello, world!")
+
+// Additional arguments can be passed after the stdin argument, as an array of
+// strings, or a sequence of varargs:
+$EXEC("ls", "" /* no stdin */, "-l", "-a")
+$EXEC("ls", "" /* no stdin */, ["-l", "-a"])
+
+// Output of running external commands is returned from $EXEC:
+print($EXEC("ls"))
+
+// apply on $EXEC
+print($EXEC.apply(this, ["ls"]));
diff --git a/samples/javahelp.js b/samples/javahelp.js
new file mode 100644
index 0000000000000000000000000000000000000000..b29be01e5a3d7cdfc52b8e89c8df4f749ba1009a
--- /dev/null
+++ b/samples/javahelp.js
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+// script helpers to print meta info on Java instances and classes
+
+// print instance methods info on a Java object or static methods info of a Java class
+function methods(jobj) {
+ if (! Java.isJavaObject(jobj)) {
+ throw new TypeError("not a Java object");
+ }
+
+ var isStatic = Java.isType(jobj);
+ var obj = Object.bindProperties({}, jobj);
+ for each (var i in obj) {
+ if (Java.isJavaMethod(i)) {
+ var str = String(i);
+ var idx = str.indexOf(' ');
+ var overloaded = str.substring(0, idx).endsWith("OverloadedDynamicMethod");
+ var lastIdx = isStatic? str.lastIndexOf('] on') : str.lastIndexOf(']');
+ print(str.substring(idx + 1, lastIdx) + (overloaded? "*" : ""))
+ }
+ }
+}
+
+// print instance field names of a Java object or static field names of a Java class
+function fields(jobj) {
+ if (! Java.isJavaObject(jobj)) {
+ throw new TypeError("not a Java object");
+ }
+
+ var obj = Object.bindProperties({}, jobj);
+ for (var i in obj) {
+ if (! Java.isJavaMethod(obj[i])) {
+ print(i);
+ }
+ }
+}
+
+undefined;
diff --git a/samples/secondssince.js b/samples/secondssince.js
new file mode 100644
index 0000000000000000000000000000000000000000..55067aa1c6f5278686575de7f2adbed83ee2120f
--- /dev/null
+++ b/samples/secondssince.js
@@ -0,0 +1,43 @@
+# usage: jjs secondssince.js
+
+/*
+ * 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.
+ */
+
+// Number of seconds elapsed since the specified Instance #nashorn #javascript #java
+// Input date and time in ISO 8601 format
+// Example: 2001-01-01T00:00:00Z for 1 Jan 2001, 0 GMT
+
+var Instant = java.time.Instant;
+var ChronoUnit = java.time.temporal.ChronoUnit;
+print("Enter date time:");
+var sec = Instant.parse(readLine()).
+ until(Instant.now(), ChronoUnit.SECONDS);
+print(sec);
diff --git a/src/jdk/internal/dynalink/DynamicLinker.java b/src/jdk/internal/dynalink/DynamicLinker.java
index 289710e2f2ad6722969c17b76aac6cbb560d78e8..26c76a140df9c78af6798fb7fdb00228f0bc545e 100644
--- a/src/jdk/internal/dynalink/DynamicLinker.java
+++ b/src/jdk/internal/dynalink/DynamicLinker.java
@@ -99,10 +99,12 @@ import jdk.internal.dynalink.support.Lookup;
import jdk.internal.dynalink.support.RuntimeContextLinkRequestImpl;
/**
- * The linker for {@link RelinkableCallSite} objects. Users of it (scripting frameworks and language runtimes) have to
- * create a linker using the {@link DynamicLinkerFactory} and invoke its link method from the invokedynamic bootstrap
- * methods to set the target of all the call sites in the code they generate. Usual usage would be to create one class
- * per language runtime to contain one linker instance as:
+ * The linker for {@link RelinkableCallSite} objects. Users of it (scripting
+ * frameworks and language runtimes) have to create a linker using the
+ * {@link DynamicLinkerFactory} and invoke its link method from the invokedynamic
+ * bootstrap methods to set the target of all the call sites in the code they
+ * generate. Usual usage would be to create one class per language runtime to
+ * contain one linker instance as:
*
*
* class MyLanguageRuntime {
@@ -123,19 +125,27 @@ import jdk.internal.dynalink.support.RuntimeContextLinkRequestImpl;
*
* Note how there are three components you will need to provide here:
*
- *
You're expected to provide a {@link GuardingDynamicLinker} for your own language. If your runtime doesn't
- * have its own language and/or object model (i.e. it's a generic scripting shell), you don't need to implement a
- * dynamic linker; you would simply not invoke the {@code setPrioritizedLinker} method on the factory, or even better,
- * simply use {@link DefaultBootstrapper}.
- *
The performance of the programs can depend on your choice of the class to represent call sites. The above
- * example used {@link MonomorphicCallSite}, but you might want to use {@link ChainedCallSite} instead. You'll need to
- * experiment and decide what fits your language runtime the best. You can subclass either of these or roll your own if
- * you need to.
- *
You also need to provide {@link CallSiteDescriptor}s to your call sites. They are immutable objects that contain
- * all the information about the call site: the class performing the lookups, the name of the method being invoked, and
- * the method signature. The library has a default {@link CallSiteDescriptorFactory} for descriptors that you can use,
- * or you can create your own descriptor classes, especially if you need to add further information (values passed in
+ *
+ *
You're expected to provide a {@link GuardingDynamicLinker} for your own
+ * language. If your runtime doesn't have its own language and/or object model
+ * (i.e., it's a generic scripting shell), you don't need to implement a dynamic
+ * linker; you would simply not invoke the {@code setPrioritizedLinker} method
+ * on the factory, or even better, simply use {@link DefaultBootstrapper}.
+ *
+ *
The performance of the programs can depend on your choice of the class to
+ * represent call sites. The above example used {@link MonomorphicCallSite}, but
+ * you might want to use {@link ChainedCallSite} instead. You'll need to
+ * experiment and decide what fits your language runtime the best. You can
+ * subclass either of these or roll your own if you need to.
+ *
+ *
You also need to provide {@link CallSiteDescriptor}s to your call sites.
+ * They are immutable objects that contain all the information about the call
+ * site: the class performing the lookups, the name of the method being invoked,
+ * and the method signature. The library has a default {@link CallSiteDescriptorFactory}
+ * for descriptors that you can use, or you can create your own descriptor
+ * classes, especially if you need to add further information (values passed in
* additional parameters to the bootstrap method) to them.
+ *
*
*
* @author Attila Szegedi
@@ -176,11 +186,15 @@ public class DynamicLinker {
}
/**
- * Links an invokedynamic call site. It will install a method handle into the call site that invokes the relinking
- * mechanism of this linker. Next time the call site is invoked, it will be linked for the actual arguments it was
- * invoked with.
+ * Links an invokedynamic call site. It will install a method handle into
+ * the call site that invokes the relinking mechanism of this linker. Next
+ * time the call site is invoked, it will be linked for the actual arguments
+ * it was invoked with.
*
+ * @param the particular subclass of {@link RelinkableCallSite} for
+ * which to create a link.
* @param callSite the call site to link.
+ *
* @return the callSite, for easy call chaining.
*/
public T link(final T callSite) {
@@ -189,10 +203,13 @@ public class DynamicLinker {
}
/**
- * Returns the object representing the lower level linker services of this class that are normally exposed to
- * individual language-specific linkers. While as a user of this class you normally only care about the
- * {@link #link(RelinkableCallSite)} method, in certain circumstances you might want to use the lower level services
- * directly; either to lookup specific method handles, to access the type converters, and so on.
+ * Returns the object representing the lower level linker services of this
+ * class that are normally exposed to individual language-specific linkers.
+ * While as a user of this class you normally only care about the
+ * {@link #link(RelinkableCallSite)} method, in certain circumstances you
+ * might want to use the lower level services directly; either to lookup
+ * specific method handles, to access the type converters, and so on.
+ *
* @return the object representing the linker services of this class.
*/
public LinkerServices getLinkerServices() {
@@ -218,7 +235,9 @@ public class DynamicLinker {
*
* @param callSite the call site itself
* @param arguments arguments to the invocation
+ *
* @return return the method handle for the invocation
+ *
* @throws Exception rethrows any exception thrown by the linkers
*/
@SuppressWarnings("unused")
@@ -272,11 +291,15 @@ public class DynamicLinker {
}
/**
- * Returns a stack trace element describing the location of the call site currently being linked on the current
- * thread. The operation internally creates a Throwable object and inspects its stack trace, so it's potentially
- * expensive. The recommended usage for it is in writing diagnostics code.
- * @return a stack trace element describing the location of the call site currently being linked, or null if it is
- * not invoked while a call site is being linked.
+ * Returns a stack trace element describing the location of the call site
+ * currently being linked on the current thread. The operation internally
+ * creates a Throwable object and inspects its stack trace, so it's
+ * potentially expensive. The recommended usage for it is in writing
+ * diagnostics code.
+ *
+ * @return a stack trace element describing the location of the call site
+ * currently being linked, or null if it is not invoked while a call
+ * site is being linked.
*/
public static StackTraceElement getLinkedCallSiteLocation() {
final StackTraceElement[] trace = new Throwable().getStackTrace();
@@ -290,8 +313,10 @@ public class DynamicLinker {
}
/**
- * Deprecated because of not precise name.
+ * Deprecated because of imprecise name.
+ *
* @deprecated Use {@link #getLinkedCallSiteLocation()} instead.
+ *
* @return see non-deprecated method
*/
@Deprecated
@@ -300,20 +325,26 @@ public class DynamicLinker {
}
/**
- * Returns true if the frame represents {@code MethodHandleNatives.linkCallSite()}, the frame immediately on top of
- * the call site frame when the call site is being linked for the first time.
+ * Returns {@code true} if the frame represents {@code MethodHandleNatives.linkCallSite()},
+ * the frame immediately on top of the call site frame when the call site is
+ * being linked for the first time.
+ *
* @param frame the frame
- * @return true if this frame represents {@code MethodHandleNatives.linkCallSite()}
+ *
+ * @return {@code true} if this frame represents {@code MethodHandleNatives.linkCallSite()}.
*/
private static boolean isInitialLinkFrame(final StackTraceElement frame) {
return testFrame(frame, INITIAL_LINK_METHOD_NAME, INITIAL_LINK_CLASS_NAME);
}
/**
- * Returns true if the frame represents {@code DynamicLinker.relink()}, the frame immediately on top of the call
- * site frame when the call site is being relinked (linked for second and subsequent times).
+ * Returns {@code true} if the frame represents {@code DynamicLinker.relink()},
+ * the frame immediately on top of the call site frame when the call site is
+ * being relinked (linked for second and subsequent times).
+ *
* @param frame the frame
- * @return true if this frame represents {@code DynamicLinker.relink()}
+ *
+ * @return {@code true} if this frame represents {@code DynamicLinker.relink()}.
*/
private static boolean isRelinkFrame(final StackTraceElement frame) {
return testFrame(frame, RELINK_METHOD_NAME, CLASS_NAME);
diff --git a/src/jdk/nashorn/api/scripting/AbstractJSObject.java b/src/jdk/nashorn/api/scripting/AbstractJSObject.java
index 55a28d7d0a77c2e9088f08facd7815f252d9ae21..9a2a39cc47a0e7bcbd3e04d6c26e21f9f6f27473 100644
--- a/src/jdk/nashorn/api/scripting/AbstractJSObject.java
+++ b/src/jdk/nashorn/api/scripting/AbstractJSObject.java
@@ -28,6 +28,7 @@ package jdk.nashorn.api.scripting;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
+import jdk.nashorn.internal.runtime.JSONListAdapter;
import jdk.nashorn.internal.runtime.JSType;
/**
@@ -282,6 +283,8 @@ public abstract class AbstractJSObject implements JSObject {
public static Object getDefaultValue(final JSObject jsobj, final Class> hint) {
if (jsobj instanceof AbstractJSObject) {
return ((AbstractJSObject)jsobj).getDefaultValue(hint);
+ } else if (jsobj instanceof JSONListAdapter) {
+ return ((JSONListAdapter)jsobj).getDefaultValue(hint);
}
return DefaultValueImpl.getDefaultValue(jsobj, hint);
}
diff --git a/src/jdk/nashorn/api/scripting/NashornScriptEngine.java b/src/jdk/nashorn/api/scripting/NashornScriptEngine.java
index dc5170690c35adb62e5bad03768df84b8b82af89..1d47dac4a9404498fb56ea5047dd48f47667f479 100644
--- a/src/jdk/nashorn/api/scripting/NashornScriptEngine.java
+++ b/src/jdk/nashorn/api/scripting/NashornScriptEngine.java
@@ -354,8 +354,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
}
}, CREATE_GLOBAL_ACC_CTXT);
- nashornContext.initGlobal(newGlobal, this);
- newGlobal.setScriptContext(ctxt);
+ nashornContext.initGlobal(newGlobal, this, ctxt);
return newGlobal;
}
@@ -404,7 +403,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
return evalImpl(script, ctxt, getNashornGlobalFrom(ctxt));
}
- private static Object evalImpl(final Context.MultiGlobalCompiledScript mgcs, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException {
+ private Object evalImpl(final Context.MultiGlobalCompiledScript mgcs, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException {
final Global oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != ctxtGlobal);
try {
@@ -413,8 +412,13 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
}
final ScriptFunction script = mgcs.getFunction(ctxtGlobal);
+ final ScriptContext oldCtxt = ctxtGlobal.getScriptContext();
ctxtGlobal.setScriptContext(ctxt);
- return ScriptObjectMirror.translateUndefined(ScriptObjectMirror.wrap(ScriptRuntime.apply(script, ctxtGlobal), ctxtGlobal));
+ try {
+ return ScriptObjectMirror.translateUndefined(ScriptObjectMirror.wrap(ScriptRuntime.apply(script, ctxtGlobal), ctxtGlobal));
+ } finally {
+ ctxtGlobal.setScriptContext(oldCtxt);
+ }
} catch (final Exception e) {
throwAsScriptException(e, ctxtGlobal);
throw new AssertionError("should not reach here");
@@ -425,7 +429,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
}
}
- private static Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException {
+ private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException {
if (script == null) {
return null;
}
@@ -436,8 +440,13 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
Context.setGlobal(ctxtGlobal);
}
+ final ScriptContext oldCtxt = ctxtGlobal.getScriptContext();
ctxtGlobal.setScriptContext(ctxt);
- return ScriptObjectMirror.translateUndefined(ScriptObjectMirror.wrap(ScriptRuntime.apply(script, ctxtGlobal), ctxtGlobal));
+ try {
+ return ScriptObjectMirror.translateUndefined(ScriptObjectMirror.wrap(ScriptRuntime.apply(script, ctxtGlobal), ctxtGlobal));
+ } finally {
+ ctxtGlobal.setScriptContext(oldCtxt);
+ }
} catch (final Exception e) {
throwAsScriptException(e, ctxtGlobal);
throw new AssertionError("should not reach here");
diff --git a/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java b/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java
index 412d4458765007c736ad7a8a69588164efe58ba8..f38244c3190f8a2398923740d320fd445266a6a2 100644
--- a/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java
+++ b/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java
@@ -178,8 +178,7 @@ public final class NashornScriptEngineFactory implements ScriptEngineFactory {
* denies {@code RuntimePermission("nashorn.setConfig")}
*/
public ScriptEngine getScriptEngine(final ClassFilter classFilter) {
- Objects.requireNonNull(classFilter);
- return newEngine(DEFAULT_OPTIONS, getAppClassLoader(), classFilter);
+ return newEngine(DEFAULT_OPTIONS, getAppClassLoader(), Objects.requireNonNull(classFilter));
}
/**
@@ -193,8 +192,7 @@ public final class NashornScriptEngineFactory implements ScriptEngineFactory {
* denies {@code RuntimePermission("nashorn.setConfig")}
*/
public ScriptEngine getScriptEngine(final String... args) {
- Objects.requireNonNull(args);
- return newEngine(args, getAppClassLoader(), null);
+ return newEngine(Objects.requireNonNull(args), getAppClassLoader(), null);
}
/**
@@ -209,8 +207,7 @@ public final class NashornScriptEngineFactory implements ScriptEngineFactory {
* denies {@code RuntimePermission("nashorn.setConfig")}
*/
public ScriptEngine getScriptEngine(final String[] args, final ClassLoader appLoader) {
- Objects.requireNonNull(args);
- return newEngine(args, appLoader, null);
+ return newEngine(Objects.requireNonNull(args), appLoader, null);
}
/**
@@ -226,9 +223,7 @@ public final class NashornScriptEngineFactory implements ScriptEngineFactory {
* denies {@code RuntimePermission("nashorn.setConfig")}
*/
public ScriptEngine getScriptEngine(final String[] args, final ClassLoader appLoader, final ClassFilter classFilter) {
- Objects.requireNonNull(args);
- Objects.requireNonNull(classFilter);
- return newEngine(args, appLoader, classFilter);
+ return newEngine(Objects.requireNonNull(args), appLoader, Objects.requireNonNull(classFilter));
}
private ScriptEngine newEngine(final String[] args, final ClassLoader appLoader, final ClassFilter classFilter) {
diff --git a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
index cabd1373366f712ec047da128afac703247829af..e3bd9c280318a1b777c87dd9533643285b3d3f55 100644
--- a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
+++ b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
@@ -47,6 +47,7 @@ import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.ConsString;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.ECMAException;
+import jdk.nashorn.internal.runtime.JSONListAdapter;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
@@ -72,6 +73,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
private final ScriptObject sobj;
private final Global global;
private final boolean strict;
+ private final boolean jsonCompatible;
@Override
public boolean equals(final Object other) {
@@ -110,9 +112,9 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
}
if (sobj instanceof ScriptFunction) {
- final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args;
- final Object self = globalChanged? wrap(thiz, oldGlobal) : thiz;
- return wrap(ScriptRuntime.apply((ScriptFunction)sobj, unwrap(self, global), unwrapArray(modArgs, global)), global);
+ final Object[] modArgs = globalChanged? wrapArrayLikeMe(args, oldGlobal) : args;
+ final Object self = globalChanged? wrapLikeMe(thiz, oldGlobal) : thiz;
+ return wrapLikeMe(ScriptRuntime.apply((ScriptFunction)sobj, unwrap(self, global), unwrapArray(modArgs, global)));
}
throw new RuntimeException("not a function: " + toString());
@@ -140,8 +142,8 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
}
if (sobj instanceof ScriptFunction) {
- final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args;
- return wrap(ScriptRuntime.construct((ScriptFunction)sobj, unwrapArray(modArgs, global)), global);
+ final Object[] modArgs = globalChanged? wrapArrayLikeMe(args, oldGlobal) : args;
+ return wrapLikeMe(ScriptRuntime.construct((ScriptFunction)sobj, unwrapArray(modArgs, global)));
}
throw new RuntimeException("not a constructor: " + toString());
@@ -170,7 +172,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
return Context.getContext();
}
}, GET_CONTEXT_ACC_CTXT);
- return wrap(context.eval(global, s, sobj, null, false), global);
+ return wrapLikeMe(context.eval(global, s, sobj, null));
}
});
}
@@ -193,8 +195,8 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
final Object val = sobj.get(functionName);
if (val instanceof ScriptFunction) {
- final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args;
- return wrap(ScriptRuntime.apply((ScriptFunction)val, sobj, unwrapArray(modArgs, global)), global);
+ final Object[] modArgs = globalChanged? wrapArrayLikeMe(args, oldGlobal) : args;
+ return wrapLikeMe(ScriptRuntime.apply((ScriptFunction)val, sobj, unwrapArray(modArgs, global)));
} else if (val instanceof JSObject && ((JSObject)val).isFunction()) {
return ((JSObject)val).call(sobj, args);
}
@@ -218,7 +220,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
Objects.requireNonNull(name);
return inGlobal(new Callable