This commit is contained in:
Lana Steuck 2015-06-11 20:19:14 -07:00
commit a0d63f0bf4
49 changed files with 1269 additions and 346 deletions

View File

@ -0,0 +1,151 @@
# 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 Files = Java.type("java.nio.file.Files");
var FileSystems = Java.type("java.nio.file.FileSystems");
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 fs = FileSystems.getFileSystem(URI.create("jrt:/"));
var root = fs.getPath('/');
var clsToPkg = new HashMap();
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;
}
}
Files.walk(root).forEach(function(p) {
if (Files.isRegularFile(p)) {
var str = p.toString();
if (str.endsWith(".class")) {
str = str.substring(1);
var idx = str.indexOf('/');
if (idx != -1) {
str = str.substring(idx + 1);
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);
}
}
}
}
}
});
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);
}
}
})();

View File

@ -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);

50
nashorn/samples/exec.js Normal file
View File

@ -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"]));

View File

@ -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;

View File

@ -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);

View File

@ -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:
*
* <pre>
* class MyLanguageRuntime {
@ -123,19 +125,27 @@ import jdk.internal.dynalink.support.RuntimeContextLinkRequestImpl;
*
* Note how there are three components you will need to provide here:
* <ul>
* <li>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}.</li>
* <li>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.</li>
* <li>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
*
* <li>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}.</li>
*
* <li>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.</li>
*
* <li>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.</li>
*
* </ul>
*
* @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 <T> 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 extends RelinkableCallSite> 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);

View File

@ -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) {

View File

@ -255,14 +255,12 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
@Override
public void removeMember(final String name) {
Objects.requireNonNull(name);
remove(name);
remove(Objects.requireNonNull(name));
}
@Override
public void setMember(final String name, final Object value) {
Objects.requireNonNull(name);
put(name, value);
put(Objects.requireNonNull(name), value);
}
@Override
@ -429,7 +427,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
@Override
public void putAll(final Map<? extends String, ? extends Object> map) {
Objects.requireNonNull(map, "map is null");
Objects.requireNonNull(map);
final ScriptObject oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != global);
inGlobal(new Callable<Object>() {

View File

@ -78,8 +78,7 @@ public final class URLReader extends Reader {
* @throws NullPointerException if url is null
*/
public URLReader(final URL url, final Charset cs) {
Objects.requireNonNull(url);
this.url = url;
this.url = Objects.requireNonNull(url);
this.cs = cs;
}

View File

@ -58,15 +58,13 @@ final class ParserImpl implements Parser {
@Override
public CompilationUnitTree parse(final File file, final DiagnosticListener listener) throws IOException, NashornException {
Objects.requireNonNull(file);
final Source src = Source.sourceFor(file.getName(), file);
final Source src = Source.sourceFor(Objects.requireNonNull(file).getName(), file);
return translate(makeParser(src, listener).parse());
}
@Override
public CompilationUnitTree parse(final Path path, final DiagnosticListener listener) throws IOException, NashornException {
Objects.requireNonNull(path);
final Source src = Source.sourceFor(path.toString(), path);
final Source src = Source.sourceFor(Objects.requireNonNull(path).toString(), path);
return translate(makeParser(src, listener).parse());
}
@ -78,9 +76,7 @@ final class ParserImpl implements Parser {
@Override
public CompilationUnitTree parse(final String name, final Reader reader, final DiagnosticListener listener) throws IOException, NashornException {
Objects.requireNonNull(name);
Objects.requireNonNull(reader);
final Source src = Source.sourceFor(name, reader);
final Source src = Source.sourceFor(Objects.requireNonNull(name), Objects.requireNonNull(reader));
return translate(makeParser(src, listener).parse());
}
@ -92,8 +88,7 @@ final class ParserImpl implements Parser {
@Override
public CompilationUnitTree parse(final ScriptObjectMirror scriptObj, final DiagnosticListener listener) throws NashornException {
Objects.requireNonNull(scriptObj);
final Map<?,?> map = scriptObj;
final Map<?,?> map = Objects.requireNonNull(scriptObj);
if (map.containsKey("script") && map.containsKey("name")) {
final String script = JSType.toString(map.get("script"));
final String name = JSType.toString(map.get("name"));

View File

@ -100,7 +100,6 @@ import jdk.nashorn.internal.runtime.Source;
* There is also a very nice debug interface that can emit formatted
* bytecodes that have been written. This is enabled by setting the
* environment "nashorn.codegen.debug" to true, or --log=codegen:{@literal <level>}
* <p>
*
* @see Compiler
*/
@ -144,7 +143,7 @@ public class ClassEmitter {
/**
* Constructor - only used internally in this class as it breaks
* abstraction towards ASM or other code generator below
* abstraction towards ASM or other code generator below.
*
* @param env script environment
* @param cw ASM classwriter
@ -157,7 +156,8 @@ public class ClassEmitter {
}
/**
* Return the method names encountered
* Return the method names encountered.
*
* @return method names
*/
public Set<String> getMethodNames() {
@ -165,12 +165,13 @@ public class ClassEmitter {
}
/**
* Constructor
* Constructor.
*
* @param env script environment
* @param className name of class to weave
* @param superClassName super class name for class
* @param interfaceNames names of interfaces implemented by this class, or null if none
* @param interfaceNames names of interfaces implemented by this class, or
* {@code null} if none
*/
ClassEmitter(final Context context, final String className, final String superClassName, final String... interfaceNames) {
this(context, new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS));
@ -178,7 +179,7 @@ public class ClassEmitter {
}
/**
* Constructor from the compiler
* Constructor from the compiler.
*
* @param env Script environment
* @param sourceName Source name
@ -217,7 +218,6 @@ public class ClassEmitter {
}
/**
* Returns the name of the compile unit class name.
* @return the name of the compile unit class name.
*/
String getUnitClassName() {
@ -225,7 +225,8 @@ public class ClassEmitter {
}
/**
* Get the method count, including init and clinit methods
* Get the method count, including init and clinit methods.
*
* @return method count
*/
public int getMethodCount() {
@ -233,7 +234,8 @@ public class ClassEmitter {
}
/**
* Get the clinit count
* Get the clinit count.
*
* @return clinit count
*/
public int getClinitCount() {
@ -241,7 +243,8 @@ public class ClassEmitter {
}
/**
* Get the init count
* Get the init count.
*
* @return init count
*/
public int getInitCount() {
@ -249,7 +252,8 @@ public class ClassEmitter {
}
/**
* Get the field count
* Get the field count.
*
* @return field count
*/
public int getFieldCount() {
@ -260,6 +264,7 @@ public class ClassEmitter {
* Convert a binary name to a package/class name.
*
* @param name Binary name.
*
* @return Package/class name.
*/
private static String pathName(final String name) {
@ -268,6 +273,7 @@ public class ClassEmitter {
/**
* Define the static fields common in all scripts.
*
* @param strictMode Should we generate this method in strict mode
*/
private void defineCommonStatics(final boolean strictMode) {
@ -284,8 +290,8 @@ public class ClassEmitter {
}
/**
* Define static utilities common needed in scripts. These are per compile unit
* and therefore have to be defined here and not in code gen.
* Define static utilities common needed in scripts. These are per compile
* unit and therefore have to be defined here and not in code gen.
*/
private void defineCommonUtilities() {
assert unitClassName != null;
@ -333,7 +339,9 @@ public class ClassEmitter {
}
/**
* Constructs a primitive specific method for getting the ith entry from the constants table as an array.
* Constructs a primitive specific method for getting the ith entry from the
* constants table as an array.
*
* @param clazz Array class.
*/
private void defineGetArrayMethod(final Class<?> clazz) {
@ -356,7 +364,9 @@ public class ClassEmitter {
/**
* Generate the name of a get array from constant pool method.
*
* @param clazz Name of array class.
*
* @return Method name.
*/
static String getArrayMethodName(final Class<?> clazz) {
@ -366,6 +376,7 @@ public class ClassEmitter {
/**
* Ensure a get constant method is issued for the class.
*
* @param clazz Class of constant.
*/
void needGetConstantMethod(final Class<?> clazz) {
@ -373,12 +384,12 @@ public class ClassEmitter {
}
/**
* Inspect class name and decide whether we are generating a ScriptObject class
* Inspect class name and decide whether we are generating a ScriptObject class.
*
* @param scriptPrefix the script class prefix for the current script
* @param type the type to check
*
* @return true if type is ScriptObject
* @return {@code true} if type is ScriptObject
*/
private static boolean isScriptObject(final String scriptPrefix, final String type) {
if (type.startsWith(scriptPrefix)) {
@ -393,14 +404,14 @@ public class ClassEmitter {
}
/**
* Call at beginning of class emission
* Call at beginning of class emission.
*/
public void begin() {
classStarted = true;
}
/**
* Call at end of class emission
* Call at end of class emission.
*/
public void end() {
assert classStarted : "class not started for " + unitClassName;
@ -424,7 +435,9 @@ public class ClassEmitter {
/**
* Disassemble an array of byte code.
*
* @param bytecode byte array representing bytecode
*
* @return disassembly as human readable string
*/
static String disassemble(final byte[] bytecode) {
@ -446,7 +459,7 @@ public class ClassEmitter {
}
/**
* Call back from MethodEmitter for method start
* Call back from MethodEmitter for method start.
*
* @see MethodEmitter
*
@ -458,7 +471,7 @@ public class ClassEmitter {
}
/**
* Call back from MethodEmitter for method end
* Call back from MethodEmitter for method end.
*
* @see MethodEmitter
*
@ -470,7 +483,7 @@ public class ClassEmitter {
}
/**
* Add a new method to the class - defaults to public method
* Add a new method to the class - defaults to public method.
*
* @param methodName name of method
* @param rtype return type of the method
@ -483,7 +496,7 @@ public class ClassEmitter {
}
/**
* Add a new method to the class - defaults to public method
* Add a new method to the class - defaults to public method.
*
* @param methodFlags access flags for the method
* @param methodName name of method
@ -499,7 +512,7 @@ public class ClassEmitter {
}
/**
* Add a new method to the class - defaults to public method
* Add a new method to the class - defaults to public method.
*
* @param methodName name of method
* @param descriptor descriptor of method
@ -511,7 +524,7 @@ public class ClassEmitter {
}
/**
* Add a new method to the class - defaults to public method
* Add a new method to the class - defaults to public method.
*
* @param methodFlags access flags for the method
* @param methodName name of method
@ -526,9 +539,10 @@ public class ClassEmitter {
}
/**
* Add a new method to the class, representing a function node
* Add a new method to the class, representing a function node.
*
* @param functionNode the function node to generate a method for
*
* @return method emitter to use for weaving this method
*/
MethodEmitter method(final FunctionNode functionNode) {
@ -546,9 +560,11 @@ public class ClassEmitter {
}
/**
* Add a new method to the class, representing a rest-of version of the function node
* Add a new method to the class, representing a rest-of version of the
* function node.
*
* @param functionNode the function node to generate a method for
*
* @return method emitter to use for weaving this method
*/
MethodEmitter restOfMethod(final FunctionNode functionNode) {
@ -566,7 +582,7 @@ public class ClassEmitter {
/**
* Start generating the <clinit> method in the class
* Start generating the <clinit> method in the class.
*
* @return method emitter to use for weaving <clinit>
*/
@ -576,7 +592,7 @@ public class ClassEmitter {
}
/**
* Start generating an <init>()V method in the class
* Start generating an <init>()V method in the class.
*
* @return method emitter to use for weaving <init>()V
*/
@ -586,7 +602,7 @@ public class ClassEmitter {
}
/**
* Start generating an <init>()V method in the class
* Start generating an <init>()V method in the class.
*
* @param ptypes parameter types for constructor
* @return method emitter to use for weaving <init>()V
@ -597,7 +613,7 @@ public class ClassEmitter {
}
/**
* Start generating an <init>(...)V method in the class
* Start generating an <init>(...)V method in the class.
*
* @param flags access flags for the constructor
* @param ptypes parameter types for the constructor
@ -610,7 +626,7 @@ public class ClassEmitter {
}
/**
* Add a field to the class, initialized to a value
* Add a field to the class, initialized to a value.
*
* @param fieldFlags flags, e.g. should it be static or public etc
* @param fieldName name of field
@ -625,7 +641,7 @@ public class ClassEmitter {
}
/**
* Add a field to the class
* Add a field to the class.
*
* @param fieldFlags access flags for the field
* @param fieldName name of field
@ -638,7 +654,7 @@ public class ClassEmitter {
}
/**
* Add a field to the class - defaults to public
* Add a field to the class - defaults to public.
*
* @param fieldName name of field
* @param fieldType type of field
@ -651,7 +667,8 @@ public class ClassEmitter {
* Return a bytecode array from this ClassEmitter. The ClassEmitter must
* have been ended (having its end function called) for this to work.
*
* @return byte code array for generated class, null if class generation hasn't been ended with {@link ClassEmitter#end()}
* @return byte code array for generated class, {@code null} if class
* generation hasn't been ended with {@link ClassEmitter#end()}.
*/
byte[] toByteArray() {
assert classEnded;
@ -663,13 +680,9 @@ public class ClassEmitter {
}
/**
* Abstraction for flags used in class emission
*
* We provide abstraction separating these from the underlying bytecode
* emitter.
*
* Flags are provided for method handles, protection levels, static/virtual
* fields/methods.
* Abstraction for flags used in class emission. We provide abstraction
* separating these from the underlying bytecode emitter. Flags are provided
* for method handles, protection levels, static/virtual fields/methods.
*/
static enum Flag {
/** method handle with static access */
@ -707,10 +720,12 @@ public class ClassEmitter {
}
/**
* Return the corresponding ASM flag value for an enum set of flags
* Return the corresponding ASM flag value for an enum set of flags.
*
* @param flags enum set of flags
* @return an integer value representing the flags intrinsic values or:ed together
*
* @return an integer value representing the flags intrinsic values
* or:ed together
*/
static int getValue(final EnumSet<Flag> flags) {
int v = 0;

View File

@ -122,8 +122,7 @@ public final class CompileUnit implements Comparable<CompileUnit>, Serializable
* @param clazz class with code for this compile unit
*/
void setCode(final Class<?> clazz) {
Objects.requireNonNull(clazz);
this.clazz = clazz;
this.clazz = Objects.requireNonNull(clazz);
// Revisit this - refactor to avoid null-ed out non-final fields
// null out emitter
this.classEmitter = null;

View File

@ -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
@ -31,11 +31,13 @@ import jdk.nashorn.internal.runtime.Debug;
import jdk.nashorn.internal.runtime.Source;
/**
* A class that tracks the current lexical context of node visitation as a stack of {@link Block} nodes. Has special
* methods to retrieve useful subsets of the context.
* A class that tracks the current lexical context of node visitation as a stack
* of {@link Block} nodes. Has special methods to retrieve useful subsets of the
* context.
*
* This is implemented with a primitive array and a stack pointer, because it really makes a difference
* performance wise. None of the collection classes were optimal
* This is implemented with a primitive array and a stack pointer, because it
* really makes a difference performance-wise. None of the collection classes
* were optimal.
*/
public class LexicalContext {
private LexicalContextNode[] stack;
@ -79,6 +81,7 @@ public class LexicalContext {
* {@link Block#NEEDS_SCOPE} because it atomically also sets the
* {@link FunctionNode#HAS_SCOPE_BLOCK} flag on the block's containing
* function.
*
* @param block the block that needs to be marked as creating a scope.
*/
public void setBlockNeedsScope(final Block block) {
@ -97,8 +100,10 @@ public class LexicalContext {
}
/**
* Get the flags for a lexical context node on the stack
* Get the flags for a lexical context node on the stack.
*
* @param node node
*
* @return the flags for the node
*/
public int getFlags(final LexicalContextNode node) {
@ -112,8 +117,10 @@ public class LexicalContext {
/**
* Get the function body of a function node on the lexical context
* stack. This will trigger an assertion if node isn't present
* stack. This will trigger an assertion if node isn't present.
*
* @param functionNode function node
*
* @return body of function node
*/
public Block getFunctionBody(final FunctionNode functionNode) {
@ -126,15 +133,16 @@ public class LexicalContext {
}
/**
* Return all nodes in the LexicalContext
* @return all nodes
* @return all nodes in the LexicalContext.
*/
public Iterator<LexicalContextNode> getAllNodes() {
return new NodeIterator<>(LexicalContextNode.class);
}
/**
* Returns the outermost function in this context. It is either the program, or a lazily compiled function.
* Returns the outermost function in this context. It is either the program,
* or a lazily compiled function.
*
* @return the outermost function in this context.
*/
public FunctionNode getOutermostFunction() {
@ -142,8 +150,12 @@ public class LexicalContext {
}
/**
* Pushes a new block on top of the context, making it the innermost open block.
* Pushes a new block on top of the context, making it the innermost open
* block.
*
* @param <T> the type of the new node
* @param node the new node
*
* @return the node that was pushed
*/
public <T extends LexicalContextNode> T push(final T node) {
@ -168,25 +180,28 @@ public class LexicalContext {
/**
* Is the context empty?
* @return true if empty
*
* @return {@code true} if empty
*/
public boolean isEmpty() {
return sp == 0;
}
/**
* The depth of the lexical context
* @return depth
* @return the depth of the lexical context.
*/
public int size() {
return sp;
}
/**
* Pops the innermost block off the context and all nodes that has been contributed
* since it was put there
* Pops the innermost block off the context and all nodes that has been
* contributed since it was put there.
*
* @param <T> the type of the node to be popped
* @param node the node expected to be popped, used to detect unbalanced
* pushes/pops
*
* @param node the node expected to be popped, used to detect unbalanced pushes/pops
* @return the node that was popped
*/
@SuppressWarnings("unchecked")
@ -202,11 +217,17 @@ public class LexicalContext {
}
/**
* 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(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.
* 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(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 <T> the type of the node to apply the flags to.
* @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)
*/
public <T extends LexicalContextNode & Flags<T>> T applyTopFlags(final T node) {
@ -215,7 +236,8 @@ public class LexicalContext {
}
/**
* Return the top element in the context
* Return the top element in the context.
*
* @return the node that was pushed last
*/
public LexicalContextNode peek() {
@ -223,9 +245,11 @@ public class LexicalContext {
}
/**
* Check if a node is in the lexical context
* Check if a node is in the lexical context.
*
* @param node node to check for
* @return true if in the context
*
* @return {@code true} if in the context
*/
public boolean contains(final LexicalContextNode node) {
for (int i = 0; i < sp; i++) {
@ -242,6 +266,7 @@ public class LexicalContext {
*
* @param oldNode old node
* @param newNode new node
*
* @return the new node
*/
public LexicalContextNode replace(final LexicalContextNode oldNode, final LexicalContextNode newNode) {
@ -256,7 +281,9 @@ public class LexicalContext {
}
/**
* Returns an iterator over all blocks in the context, with the top block (innermost lexical context) first.
* Returns an iterator over all blocks in the context, with the top block
* (innermost lexical context) first.
*
* @return an iterator over all blocks in the context.
*/
public Iterator<Block> getBlocks() {
@ -264,7 +291,9 @@ public class LexicalContext {
}
/**
* Returns an iterator over all functions in the context, with the top (innermost open) function first.
* Returns an iterator over all functions in the context, with the top
* (innermost open) function first.
*
* @return an iterator over all functions in the context.
*/
public Iterator<FunctionNode> getFunctions() {
@ -273,6 +302,7 @@ public class LexicalContext {
/**
* Get the parent block for the current lexical context block
*
* @return parent block
*/
public Block getParentBlock() {
@ -283,7 +313,9 @@ public class LexicalContext {
/**
* Gets the label node of the current block.
* @return the label node of the current block, if it is labeled. Otherwise returns null.
*
* @return the label node of the current block, if it is labeled. Otherwise
* returns {@code null}.
*/
public LabelNode getCurrentBlockLabelNode() {
assert stack[sp - 1] instanceof Block;
@ -294,21 +326,12 @@ public class LexicalContext {
return parent instanceof LabelNode ? (LabelNode)parent : null;
}
/*
public FunctionNode getProgram() {
final Iterator<FunctionNode> iter = getFunctions();
FunctionNode last = null;
while (iter.hasNext()) {
last = iter.next();
}
assert last != null;
return last;
}*/
/**
* Returns an iterator over all ancestors block of the given block, with its parent block first.
* Returns an iterator over all ancestors block of the given block, with its
* parent block first.
*
* @param block the block whose ancestors are returned
*
* @return an iterator over all ancestors block of the given block.
*/
public Iterator<Block> getAncestorBlocks(final Block block) {
@ -323,8 +346,11 @@ public class LexicalContext {
}
/**
* Returns an iterator over a block and all its ancestors blocks, with the block first.
* Returns an iterator over a block and all its ancestors blocks, with the
* block first.
*
* @param block the block that is the starting point of the iteration.
*
* @return an iterator over a block and all its ancestors.
*/
public Iterator<Block> getBlocks(final Block block) {
@ -352,7 +378,9 @@ public class LexicalContext {
/**
* Get the function for this block.
*
* @param block block for which to get function
*
* @return function for block
*/
public FunctionNode getFunction(final Block block) {
@ -373,7 +401,6 @@ public class LexicalContext {
}
/**
* Returns the innermost block in the context.
* @return the innermost block in the context.
*/
public Block getCurrentBlock() {
@ -381,7 +408,6 @@ public class LexicalContext {
}
/**
* Returns the innermost function in the context.
* @return the innermost function in the context.
*/
public FunctionNode getCurrentFunction() {
@ -394,9 +420,12 @@ public class LexicalContext {
}
/**
* Get the block in which a symbol is defined
* Get the block in which a symbol is defined.
*
* @param symbol symbol
* @return block in which the symbol is defined, assert if no such block in context
*
* @return block in which the symbol is defined, assert if no such block in
* context.
*/
public Block getDefiningBlock(final Symbol symbol) {
final String name = symbol.getName();
@ -410,9 +439,12 @@ public class LexicalContext {
}
/**
* Get the function in which a symbol is defined
* Get the function in which a symbol is defined.
*
* @param symbol symbol
* @return function node in which this symbol is defined, assert if no such symbol exists in context
*
* @return function node in which this symbol is defined, assert if no such
* symbol exists in context.
*/
public FunctionNode getDefiningFunction(final Symbol symbol) {
final String name = symbol.getName();
@ -433,7 +465,8 @@ public class LexicalContext {
/**
* Is the topmost lexical context element a function body?
* @return true if function body
*
* @return {@code true} if function body.
*/
public boolean isFunctionBody() {
return getParentBlock() == null;
@ -441,16 +474,20 @@ public class LexicalContext {
/**
* Is the topmost lexical context element body of a SplitNode?
* @return true if it's the body of a split node.
*
* @return {@code true} if it's the body of a split node.
*/
public boolean isSplitBody() {
return sp >= 2 && stack[sp - 1] instanceof Block && stack[sp - 2] instanceof SplitNode;
}
/**
* Get the parent function for a function in the lexical context
* Get the parent function for a function in the lexical context.
*
* @param functionNode function for which to get parent
* @return parent function of functionNode or null if none (e.g. if functionNode is the program)
*
* @return parent function of functionNode or {@code null} if none (e.g., if
* functionNode is the program).
*/
public FunctionNode getParentFunction(final FunctionNode functionNode) {
final Iterator<FunctionNode> iter = new NodeIterator<>(FunctionNode.class);
@ -465,12 +502,16 @@ public class LexicalContext {
}
/**
* Count the number of scopes until a given node. Note that this method is solely used to figure out the number of
* scopes that need to be explicitly popped in order to perform a break or continue jump within the current bytecode
* method. For this reason, the method returns 0 if it encounters a {@code SplitNode} between the current location
* and the break/continue target.
* @param until node to stop counting at. Must be within the current function
* @return number of with scopes encountered in the context
* Count the number of scopes until a given node. Note that this method is
* solely used to figure out the number of scopes that need to be explicitly
* popped in order to perform a break or continue jump within the current
* bytecode method. For this reason, the method returns 0 if it encounters a
* {@code SplitNode} between the current location and the break/continue
* target.
*
* @param until node to stop counting at. Must be within the current function.
*
* @return number of with scopes encountered in the context.
*/
public int getScopeNestingLevelTo(final LexicalContextNode until) {
assert until != null;
@ -500,16 +541,17 @@ public class LexicalContext {
}
/**
* Check whether the lexical context is currently inside a loop
* @return true if inside a loop
* Check whether the lexical context is currently inside a loop.
*
* @return {@code true} if inside a loop
*/
public boolean inLoop() {
return getCurrentLoop() != null;
}
/**
* Returns the loop header of the current loop, or null if not inside a loop
* @return loop header
* @return the loop header of the current loop, or {@code null} if not
* inside a loop.
*/
public LoopNode getCurrentLoop() {
final Iterator<LoopNode> iter = new NodeIterator<>(LoopNode.class, getCurrentFunction());
@ -518,9 +560,12 @@ public class LexicalContext {
/**
* Find the breakable node corresponding to this label.
* @param labelName name of the label to search for. If null, the closest breakable node will be returned
* unconditionally, e.g. a while loop with no label
* @return closest breakable node
*
* @param labelName name of the label to search for. If {@code null}, the
* closest breakable node will be returned unconditionally, e.g., a
* while loop with no label.
*
* @return closest breakable node.
*/
public BreakableNode getBreakable(final String labelName) {
if (labelName != null) {
@ -544,9 +589,12 @@ public class LexicalContext {
/**
* Find the continue target node corresponding to this label.
* @param labelName label name to search for. If null the closest loop node will be returned unconditionally, e.g. a
* while loop with no label
* @return closest continue target node
*
* @param labelName label name to search for. If {@code null} the closest
* loop node will be returned unconditionally, e.g., a while loop
* with no label.
*
* @return closest continue target node.
*/
public LoopNode getContinueTo(final String labelName) {
if (labelName != null) {
@ -566,8 +614,10 @@ public class LexicalContext {
/**
* Find the inlined finally block node corresponding to this label.
* @param labelName label name to search for. Must not be null.
* @return closest inlined finally block with the given label
*
* @param labelName label name to search for. Must not be {@code null}.
*
* @return closest inlined finally block with the given label.
*/
public Block getInlinedFinally(final String labelName) {
for (final NodeIterator<TryNode> iter = new NodeIterator<>(TryNode.class); iter.hasNext(); ) {
@ -581,7 +631,9 @@ public class LexicalContext {
/**
* Find the try node for an inlined finally block corresponding to this label.
* @param labelName label name to search for. Must not be null.
*
* @param labelName label name to search for. Must not be {@code null}.
*
* @return the try node to which the labelled inlined finally block belongs.
*/
public TryNode getTryNodeForInlinedFinally(final String labelName) {
@ -595,9 +647,11 @@ public class LexicalContext {
}
/**
* Check the lexical context for a given label node by name
* @param name name of the label
* @return LabelNode if found, null otherwise
* Check the lexical context for a given label node by name.
*
* @param name name of the label.
*
* @return LabelNode if found, {@code null} otherwise.
*/
private LabelNode findLabel(final String name) {
for (final Iterator<LabelNode> iter = new NodeIterator<>(LabelNode.class, getCurrentFunction()); iter.hasNext(); ) {
@ -610,10 +664,13 @@ public class LexicalContext {
}
/**
* Checks whether a given target is a jump destination that lies outside a given split node
* @param splitNode the split node
* @param target the target node
* @return true if target resides outside the split node
* Checks whether a given target is a jump destination that lies outside a
* given split node.
*
* @param splitNode the split node.
* @param target the target node.
*
* @return {@code true} if target resides outside the split node.
*/
public boolean isExternalTarget(final SplitNode splitNode, final BreakableNode target) {
for (int i = sp; i-- > 0;) {
@ -634,8 +691,10 @@ public class LexicalContext {
}
/**
* Checks whether the current context is inside a switch statement without explicit blocks (curly braces).
* @return true if in unprotected switch statement
* Checks whether the current context is inside a switch statement without
* explicit blocks (curly braces).
*
* @return {@code true} if in unprotected switch statement.
*/
public boolean inUnprotectedSwitchContext() {
for (int i = sp; i > 0; i--) {

View File

@ -1005,9 +1005,7 @@ public final class Global extends ScriptObject implements Scope {
* @return the global singleton
*/
public static Global instance() {
final Global global = Context.getGlobal();
Objects.requireNonNull(global);
return global;
return Objects.requireNonNull(Context.getGlobal());
}
private static Global instanceFrom(final Object self) {
@ -2712,6 +2710,14 @@ public final class Global extends ScriptObject implements Scope {
// Retrieve current state of ENV variables.
final ScriptObject env = newObject();
env.putAll(System.getenv(), scriptEnv._strict);
// Some platforms, e.g., Windows, do not define the PWD environment
// variable, so that the $ENV.PWD property needs to be explicitly
// set.
if (!env.containsKey(ScriptingFunctions.PWD_NAME)) {
env.put(ScriptingFunctions.PWD_NAME, System.getProperty("user.dir"), scriptEnv._strict);
}
addOwnProperty(ScriptingFunctions.ENV_NAME, Attribute.NOT_ENUMERABLE, env);
} else {
addOwnProperty(ScriptingFunctions.ENV_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED);

View File

@ -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
@ -37,13 +37,15 @@ import java.lang.annotation.Target;
@Target(ElementType.METHOD)
public @interface Constructor {
/**
* Name of the constructor function. If empty, the name is inferred.
* @return the name of the constructor function. If empty, the name is
* inferred.
*/
public String name() default "";
/**
* The arity of the function. By default computed from the method signature.
* Note that -1 means varargs. So, -2 is used as invalid arity.
* @return the arity of the function. By default computed from the method
* signature. Note that -1 means varargs. So, -2 is used as invalid
* arity.
*/
public int arity() default -2;
}

View File

@ -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
@ -41,22 +41,23 @@ import java.lang.annotation.Target;
@Target(ElementType.METHOD)
public @interface Function {
/**
* Name of the property. If empty, the name is inferred.
* @return the name of the property. If empty, the name is inferred.
*/
public String name() default "";
/**
* Attribute flags for this function.
* @return the attribute flags for this function.
*/
public int attributes() default DEFAULT_ATTRIBUTES;
/**
* The arity of the function. By default computed from the method signature
* @return the arity of the function. By default computed from the method
* signature.
*/
public int arity() default -2;
/**
* where this function lives
* @return where this function lives.
*/
public Where where() default Where.PROTOTYPE;
}

View File

@ -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
@ -39,17 +39,17 @@ import java.lang.annotation.Target;
@Target(ElementType.METHOD)
public @interface Getter {
/**
* Name of the property. If empty, the name is inferred.
* @return the name of the property. If empty, the name is inferred.
*/
public String name() default "";
/**
* Attribute flags for this setter.
* @return the attribute flags for this setter.
*/
public int attributes() default DEFAULT_ATTRIBUTES;
/**
* Where this getter lives?
* @return where this getter lives.
*/
public Where where() default Where.INSTANCE;
}

View File

@ -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
@ -37,8 +37,8 @@ import java.lang.annotation.Target;
@Target(ElementType.TYPE)
public @interface ScriptClass {
/**
* Name of the script class. By default, the name is derived from
* the Java class name.
* @return the name of the script class. By default, the name is derived
* from the Java class name.
*/
public String value() default "";
}

View File

@ -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
@ -39,17 +39,17 @@ import java.lang.annotation.Target;
@Target(ElementType.METHOD)
public @interface Setter {
/**
* Name of the script property. If empty, the name is inferred.
* @return the name of the script property. If empty, the name is inferred.
*/
public String name() default "";
/**
* Attribute flags for this setter.
* @return the attribute flags for this setter.
*/
public int attributes() default DEFAULT_ATTRIBUTES;
/**
* Where this setter lives?
* @return where this setter lives.
*/
public Where where() default Where.INSTANCE;
}

View File

@ -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
@ -33,10 +33,11 @@ import java.lang.invoke.MethodHandle;
import jdk.internal.dynalink.CallSiteDescriptor;
import jdk.internal.dynalink.linker.LinkRequest;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.UnwarrantedOptimismException;
/**
* The SpecializedFunction annotation is used to flag more type specific
* functions than the standard one in the native objects
* functions than the standard one in the native objects.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@ -45,23 +46,23 @@ public @interface SpecializedFunction {
/**
* Functionality for testing if we are allowed to link a specialized
* function the first time we encounter it. Then the guard will handle the
* rest of the invocations
* rest of the invocations.
*
* This is the same for all callsites in Nashorn, the first time callsite is
* This is the same for all callsites in Nashorn; the first time a callsite is
* linked, we have to manually check that the linkage is OK. Even if we add
* a guard and it fails upon the first try, this is not good enough.
* (Symmetrical to how it works everywhere else in the Nashorn runtime).
* (Symmetrical to how it works everywhere else in the Nashorn runtime.)
*
* Here we abstract out a few of the most common link guard checks.
*/
public static abstract class LinkLogic {
/**
* Empty link logic instance - this is the default
* Empty link logic instance - this is the default.
* "no special linking or runtime guard behavior"
*/
public static final LinkLogic EMPTY_INSTANCE = new Empty();
/** Empty link logic class - allow all linking, no guards */
/** Empty link logic class - allow all linking, no guards. */
private static final class Empty extends LinkLogic {
@Override
public boolean canLink(final Object self, final CallSiteDescriptor desc, final LinkRequest request) {
@ -75,7 +76,8 @@ public @interface SpecializedFunction {
}
/**
* Get the class representing the empty link logic
* Get the class representing the empty link logic.
*
* @return class representing empty link logic
*/
public static Class<? extends LinkLogic> getEmptyLinkLogicClass() {
@ -83,31 +85,31 @@ public @interface SpecializedFunction {
}
/**
* Should this callsite relink when an exception is thrown
* Should this callsite relink when an exception is thrown?
*
* @return the relink exception, or null if none
* @return the relink exception, or {@code null} if none
*/
public Class<? extends Throwable> getRelinkException() {
return null;
}
/**
* Is this link logic class empty - i.e. no special linking logic
* supplied
* Is this link logic class empty - i.e., no special linking logic
* supplied?
*
* @param clazz class to check
*
* @return true if this link logic is empty
* @return {@code true} if this link logic is empty
*/
public static boolean isEmpty(final Class<? extends LinkLogic> clazz) {
return clazz == Empty.class;
}
/**
* Is this link logic instance empty - i.e. no special linking logic
* supplied
* Is this link logic instance empty - i.e., no special linking logic
* supplied?
*
* @return true if this link logic instance is empty
* @return {@code true} if this link logic instance is empty
*/
public boolean isEmpty() {
return false;
@ -121,7 +123,7 @@ public @interface SpecializedFunction {
* @param desc callsite descriptor
* @param request link request
*
* @return true if we can link this callsite at this time
* @return {@code true} if we can link this callsite at this time
*/
public abstract boolean canLink(final Object self, final CallSiteDescriptor desc, final LinkRequest request);
@ -131,7 +133,7 @@ public @interface SpecializedFunction {
*
* @param self receiver
*
* @return true if a guard is to be woven into the callsite
* @return {@code true} if a guard is to be woven into the callsite
*/
public boolean needsGuard(final Object self) {
return true;
@ -139,13 +141,13 @@ public @interface SpecializedFunction {
/**
* Given a callsite, and optional arguments, do we need an extra guard
* for specialization to go through - this guard can be a function of
* the arguments too
* for specialization to go through? This guard can be a function of
* the arguments too.
*
* @param self receiver
* @param args arguments
*
* @return true if a guard is to be woven into the callsite
* @return {@code true} if a guard is to be woven into the callsite
*/
public boolean needsGuard(final Object self, final Object... args) {
return true;
@ -169,9 +171,9 @@ public @interface SpecializedFunction {
* @param self receiver
* @param desc callsite descriptor
* @param request link request
* @return true if we can link, false otherwise - that means we have to
* pick a non specialized target
*
* @return {@code true} if we can link, {@code false} otherwise - that
* means we have to pick a non specialized target
*/
public boolean checkLinkable(final Object self, final CallSiteDescriptor desc, final LinkRequest request) {
// check the link guard, if it says we can link, go ahead
@ -180,11 +182,11 @@ public @interface SpecializedFunction {
}
/**
* name override for return value polymorphism, for example we can't have
* Name override for return value polymorphism, for example we can't have
* pop(V)I and pop(V)D in the same Java class, so they need to be named,
* e.g. popInt(V)I and popDouble(V)D for disambiguation, however, their
* e.g., popInt(V)I and popDouble(V)D for disambiguation, however, their
* names still need to resolve to "pop" to JavaScript so we can still
* specialize on return values and so that the linker can find them
* specialize on return values and so that the linker can find them.
*
* @return name, "" means no override, use the Java function name, e.g.
* "push"
@ -199,16 +201,18 @@ public @interface SpecializedFunction {
Class<?> linkLogic() default LinkLogic.Empty.class;
/**
* Is this a specialized constructor?
* @return whether this is a specialized constructor.
*/
boolean isConstructor() default false;
/**
* Can this function throw UnwarrantedOptimismExceptions? This works just
* like the normal functions, but we need the function to be
* Can this function throw {@link UnwarrantedOptimismException}s? This works
* just like the normal functions, but we need the function to be
* immutable/non-state modifying, as we can't generate continuations for
* native code. Luckily a lot of the methods we want to specialize have this
* property
* property.
*
* @return whether this function can throw {@link UnwarrantedOptimismException}.
*/
boolean isOptimistic() default false;
}

View File

@ -47,7 +47,8 @@ import jdk.nashorn.internal.scripts.JO;
import static jdk.nashorn.internal.parser.TokenType.STRING;
/**
* Parses JSON text and returns the corresponding IR node. This is derived from the objectLiteral production of the main parser.
* Parses JSON text and returns the corresponding IR node. This is derived from
* the objectLiteral production of the main parser.
*
* See: 15.12.1.2 The JSON Syntactic Grammar
*/
@ -70,9 +71,11 @@ public class JSONParser {
private static final int STATE_COMMA_PARSED = 2;
/**
* Constructor
* @param source the source
* @param global the global object
* Constructor.
*
* @param source the source
* @param global the global object
* @param dualFields whether the parser should regard dual field representation
*/
public JSONParser(final String source, final Global global, final boolean dualFields) {
this.source = source;
@ -82,8 +85,9 @@ public class JSONParser {
}
/**
* Implementation of the Quote(value) operation as defined in the ECMA script spec
* It wraps a String value in double quotes and escapes characters within in
* Implementation of the Quote(value) operation as defined in the ECMAscript
* spec. It wraps a String value in double quotes and escapes characters
* within.
*
* @param value string to quote
*

View File

@ -2668,8 +2668,12 @@ loop:
name = getIdent();
verifyStrictIdent(name, "function name");
} else if (isStatement) {
// Nashorn extension: anonymous function statements
if (env._no_syntax_extensions) {
// Nashorn extension: anonymous function statements.
// Do not allow anonymous function statement if extensions
// are now allowed. But if we are reparsing then anon function
// statement is possible - because it was used as function
// expression in surrounding code.
if (env._no_syntax_extensions && reparsedFunction == null) {
expect(IDENT);
}
}

View File

@ -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
@ -222,9 +222,11 @@ public enum TokenType {
/**
* Determines if the token has greater precedence than other.
*
* @param other Compare token.
* @param isLeft Is to the left of the other.
* @return True if greater precedence.
*
* @return {@code true} if greater precedence.
*/
public boolean needsParens(final TokenType other, final boolean isLeft) {
return other.precedence != 0 &&
@ -234,16 +236,16 @@ public enum TokenType {
/**
* Determines if the type is a valid operator.
* @param noIn TRUE if IN operator should be ignored.
* @return TRUE if valid operator.
*
* @param noIn {@code true} if IN operator should be ignored.
*
* @return {@code true} if valid operator.
*/
public boolean isOperator(final boolean noIn) {
return kind == BINARY && (!noIn || this != IN) && precedence != 0;
}
/**
* Accessors.
*/
public int getLength() {
assert name != null : "Token name not set";
return name.length();

View File

@ -70,7 +70,6 @@ final class ScriptLoader extends NashornLoader {
* @return Installed class.
*/
synchronized Class<?> installClass(final String name, final byte[] data, final CodeSource cs) {
Objects.requireNonNull(cs);
return defineClass(name, data, 0, data.length, cs);
return defineClass(name, data, 0, data.length, Objects.requireNonNull(cs));
}
}

View File

@ -2582,7 +2582,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
final int callCount = callType.parameterCount();
final boolean isCalleeVarArg = parameterCount > 0 && methodType.parameterType(parameterCount - 1).isArray();
final boolean isCallerVarArg = callerVarArg != null ? callerVarArg.booleanValue() : callCount > 0 &&
final boolean isCallerVarArg = callerVarArg != null ? callerVarArg : callCount > 0 &&
callType.parameterType(callCount - 1).isArray();
if (isCalleeVarArg) {

View File

@ -39,8 +39,10 @@ import java.io.StringReader;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import jdk.nashorn.internal.objects.NativeArray;
/**
* Global functions supported only in scripting mode.
@ -54,7 +56,7 @@ public final class ScriptingFunctions {
public static final MethodHandle READFULLY = findOwnMH("readFully", Object.class, Object.class, Object.class);
/** Handle to implementation of {@link ScriptingFunctions#exec} - Nashorn extension */
public static final MethodHandle EXEC = findOwnMH("exec", Object.class, Object.class, Object.class, Object.class);
public static final MethodHandle EXEC = findOwnMH("exec", Object.class, Object.class, Object[].class);
/** EXEC name - special property used by $EXEC API. */
public static final String EXEC_NAME = "$EXEC";
@ -71,7 +73,8 @@ public final class ScriptingFunctions {
/** Names of special properties used by $ENV API. */
public static final String ENV_NAME = "$ENV";
private static final String PWD_NAME = "PWD";
/** Name of the environment variable for the current working directory. */
public static final String PWD_NAME = "PWD";
private ScriptingFunctions() {
}
@ -125,19 +128,32 @@ public final class ScriptingFunctions {
* Nashorn extension: exec a string in a separate process.
*
* @param self self reference
* @param string string to execute
* @param input input
* @param args string to execute, input and additional arguments, to be appended to {@code string}. Additional arguments can be passed as
* either one JavaScript array, whose elements will be converted to strings; or as a sequence of
* varargs, each of which will be converted to a string.
*
* @return output string from the request
*
* @throws IOException if any stream access fails
* @throws InterruptedException if execution is interrupted
*/
public static Object exec(final Object self, final Object string, final Object input) throws IOException, InterruptedException {
public static Object exec(final Object self, final Object... args) throws IOException, InterruptedException {
// Current global is need to fetch additional inputs and for additional results.
final ScriptObject global = Context.getGlobal();
final Object string = args.length > 0? args[0] : UNDEFINED;
final Object input = args.length > 1? args[1] : UNDEFINED;
final Object[] argv = (args.length > 2)? Arrays.copyOfRange(args, 2, args.length) : ScriptRuntime.EMPTY_ARRAY;
// Assemble command line, process additional arguments.
final List<String> cmdLine = tokenizeString(JSType.toString(string));
final Object[] additionalArgs = argv.length == 1 && argv[0] instanceof NativeArray ?
((NativeArray) argv[0]).asObjectArray() :
argv;
for (Object arg : additionalArgs) {
cmdLine.add(JSType.toString(arg));
}
// Set up initial process.
final ProcessBuilder processBuilder = new ProcessBuilder(tokenizeString(JSType.toString(string)));
final ProcessBuilder processBuilder = new ProcessBuilder(cmdLine);
// Current ENV property state.
final Object env = global.get(ENV_NAME);

View File

@ -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
@ -54,23 +54,28 @@ import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
/**
* <p>A factory class that generates adapter classes. Adapter classes allow implementation of Java interfaces and
* extending of Java classes from JavaScript. For every combination of a superclass to extend and interfaces to
* implement (collectively: "original types"), exactly one adapter class is generated that extends the specified
* superclass and implements the specified interfaces. (But see the discussion of class-based overrides for exceptions.)
* </p><p>
* The adapter class is generated in a new secure class loader that inherits Nashorn's protection domain, and has either
* one of the original types' class loader or the Nashorn's class loader as its parent - the parent class loader
* is chosen so that all the original types and the Nashorn core classes are visible from it (as the adapter will have
* constant pool references to ScriptObject and ScriptFunction classes). In case none of the candidate class loaders has
* visibility of all the required types, an error is thrown. The class uses {@link JavaAdapterBytecodeGenerator} to
* generate the adapter class itself; see its documentation for details about the generated class.
* </p><p>
* You normally don't use this class directly, but rather either create adapters from script using
* {@link jdk.nashorn.internal.objects.NativeJava#extend(Object, Object...)}, using the {@code new} operator on abstract classes and interfaces (see
* {@link jdk.nashorn.internal.objects.NativeJava#type(Object, Object)}), or implicitly when passing script functions to Java methods expecting SAM
* types.
* </p>
* A factory class that generates adapter classes. Adapter classes allow
* implementation of Java interfaces and extending of Java classes from
* JavaScript. For every combination of a superclass to extend and interfaces to
* implement (collectively: "original types"), exactly one adapter class is
* generated that extends the specified superclass and implements the specified
* interfaces. (But see the discussion of class-based overrides for exceptions.)
* <p>
* The adapter class is generated in a new secure class loader that inherits
* Nashorn's protection domain, and has either one of the original types' class
* loader or the Nashorn's class loader as its parent - the parent class loader
* is chosen so that all the original types and the Nashorn core classes are
* visible from it (as the adapter will have constant pool references to
* ScriptObject and ScriptFunction classes). In case none of the candidate class
* loaders has visibility of all the required types, an error is thrown. The
* class uses {@link JavaAdapterBytecodeGenerator} to generate the adapter class
* itself; see its documentation for details about the generated class.
* <p>
* You normally don't use this class directly, but rather either create adapters
* from script using {@link jdk.nashorn.internal.objects.NativeJava#extend(Object, Object...)},
* using the {@code new} operator on abstract classes and interfaces (see
* {@link jdk.nashorn.internal.objects.NativeJava#type(Object, Object)}), or
* implicitly when passing script functions to Java methods expecting SAM types.
*/
@SuppressWarnings("javadoc")
@ -93,25 +98,39 @@ public final class JavaAdapterFactory {
};
/**
* Returns an adapter class for the specified original types. The adapter class extends/implements the original
* class/interfaces.
* @param types the original types. The caller must pass at least one Java type representing either a public
* interface or a non-final public class with at least one public or protected constructor. If more than one type is
* specified, at most one can be a class and the rest have to be interfaces. The class can be in any position in the
* array. Invoking the method twice with exactly the same types in the same order will return the same adapter
* class, any reordering of types or even addition or removal of redundant types (i.e. interfaces that other types
* in the list already implement/extend, or {@code java.lang.Object} in a list of types consisting purely of
* interfaces) will result in a different adapter class, even though those adapter classes are functionally
* identical; we deliberately don't want to incur the additional processing cost of canonicalizing type lists.
* @param classOverrides a JavaScript object with functions serving as the class-level overrides and
* implementations. These overrides are defined for all instances of the class, and can be further overridden on a
* per-instance basis by passing additional objects in the constructor.
* @param lookup the lookup object identifying the caller class. The generated adapter class will have the
* protection domain of the caller class iff the lookup object is full-strength, otherwise it will be completely
* unprivileged.
* @return an adapter class. See this class' documentation for details on the generated adapter class.
* @throws ECMAException with a TypeError if the adapter class can not be generated because the original class is
* final, non-public, or has no public or protected constructors.
* Returns an adapter class for the specified original types. The adapter
* class extends/implements the original class/interfaces.
*
* @param types the original types. The caller must pass at least one Java
* type representing either a public interface or a non-final public
* class with at least one public or protected constructor. If more
* than one type is specified, at most one can be a class and the
* rest have to be interfaces. The class can be in any position in
* the array. Invoking the method twice with exactly the same types
* in the same order will return the same adapter class, any
* reordering of types or even addition or removal of redundant types
* (i.e., interfaces that other types in the list already
* implement/extend, or {@code java.lang.Object} in a list of types
* consisting purely of interfaces) will result in a different
* adapter class, even though those adapter classes are functionally
* identical; we deliberately don't want to incur the additional
* processing cost of canonicalizing type lists.
* @param classOverrides a JavaScript object with functions serving as the
* class-level overrides and implementations. These overrides are
* defined for all instances of the class, and can be further
* overridden on a per-instance basis by passing additional objects
* in the constructor.
* @param lookup the lookup object identifying the caller class. The
* generated adapter class will have the protection domain of the
* caller class iff the lookup object is full-strength, otherwise it
* will be completely unprivileged.
*
* @return an adapter class. See this class' documentation for details on
* the generated adapter class.
*
* @throws ECMAException with a TypeError if the adapter class can not be
* generated because the original class is final, non-public, or has
* no public or protected constructors.
*/
public static StaticClass getAdapterClassFor(final Class<?>[] types, final ScriptObject classOverrides, final MethodHandles.Lookup lookup) {
return getAdapterClassFor(types, classOverrides, getProtectionDomain(lookup));
@ -148,15 +167,23 @@ public final class JavaAdapterFactory {
}
/**
* Returns a method handle representing a constructor that takes a single argument of the source type (which,
* really, should be one of {@link ScriptObject}, {@link ScriptFunction}, or {@link Object}, and returns an instance
* of the adapter for the target type. Used to implement the function autoconverters as well as the Nashorn's
* JSR-223 script engine's {@code getInterface()} method.
* @param sourceType the source type; should be either {@link ScriptObject}, {@link ScriptFunction}, or
* {@link Object}. In case of {@code Object}, it will return a method handle that dispatches to either the script
* object or function constructor at invocation based on the actual argument.
* Returns a method handle representing a constructor that takes a single
* argument of the source type (which, really, should be one of {@link ScriptObject},
* {@link ScriptFunction}, or {@link Object}, and returns an instance of the
* adapter for the target type. Used to implement the function autoconverters
* as well as the Nashorn JSR-223 script engine's {@code getInterface()}
* method.
*
* @param sourceType the source type; should be either {@link ScriptObject},
* {@link ScriptFunction}, or {@link Object}. In case of {@code Object},
* it will return a method handle that dispatches to either the script
* object or function constructor at invocation based on the actual
* argument.
* @param targetType the target type, for which adapter instances will be created
* @param lookup method handle lookup to use
*
* @return the constructor method handle.
*
* @throws Exception if anything goes wrong
*/
public static MethodHandle getConstructor(final Class<?> sourceType, final Class<?> targetType, final MethodHandles.Lookup lookup) throws Exception {
@ -168,13 +195,18 @@ public final class JavaAdapterFactory {
}
/**
* Returns whether an instance of the specified class/interface can be generated from a ScriptFunction. Returns true
* iff: the adapter for the class/interface can be created, it is abstract (this includes interfaces), it has at
* least one abstract method, all the abstract methods share the same name, and it has a public or protected default
* constructor. Note that invoking this class will most likely result in the adapter class being defined in the JVM
* if it hasn't been already.
* Returns whether an instance of the specified class/interface can be
* generated from a ScriptFunction. Returns {@code true} iff: the adapter
* for the class/interface can be created, it is abstract (this includes
* interfaces), it has at least one abstract method, all the abstract
* methods share the same name, and it has a public or protected default
* constructor. Note that invoking this class will most likely result in the
* adapter class being defined in the JVM if it hasn't been already.
*
* @param clazz the inspected class
* @return true iff an instance of the specified class/interface can be generated from a ScriptFunction.
*
* @return {@code true} iff an instance of the specified class/interface can
* be generated from a ScriptFunction.
*/
static boolean isAutoConvertibleFromFunction(final Class<?> clazz) {
return getAdapterInfo(new Class<?>[] { clazz }).autoConvertibleFromFunction;
@ -198,7 +230,9 @@ public final class JavaAdapterFactory {
/**
* For a given class, create its adapter class and associated info.
*
* @param type the class for which the adapter is created
*
* @return the adapter info for the class.
*/
private static AdapterInfo createAdapterInfo(final Class<?>[] types, final ClassAndLoader definingClassAndLoader) {
@ -311,11 +345,14 @@ public final class JavaAdapterFactory {
}
/**
* Choose between the passed class loader and the class loader that defines the ScriptObject class, based on which
* of the two can see the classes in both.
* @param classAndLoader the loader and a representative class from it that will be used to add the generated
* adapter to its ADAPTER_INFO_MAPS.
* Choose between the passed class loader and the class loader that defines the
* ScriptObject class, based on which of the two can see the classes in both.
*
* @param classAndLoader the loader and a representative class from it that will
* be used to add the generated adapter to its ADAPTER_INFO_MAPS.
*
* @return the class loader that sees both the specified class and Nashorn classes.
*
* @throws IllegalStateException if no such class loader is found.
*/
private static ClassLoader findCommonLoader(final ClassAndLoader classAndLoader) throws AdaptationException {

View File

@ -36,8 +36,7 @@ class JavaSuperAdapter {
private final Object adapter;
JavaSuperAdapter(final Object adapter) {
Objects.requireNonNull(adapter);
this.adapter = adapter;
this.adapter = Objects.requireNonNull(adapter);
}
public Object getAdapter() {

View File

@ -136,6 +136,12 @@ public final class Options {
return options.toString();
}
private static void checkPropertyName(final String name) {
if (! Objects.requireNonNull(name).startsWith("nashorn.")) {
throw new IllegalArgumentException(name);
}
}
/**
* Convenience function for getting system properties in a safe way
@ -144,11 +150,7 @@ public final class Options {
* @return true if set to true, default value if unset or set to false
*/
public static boolean getBooleanProperty(final String name, final Boolean defValue) {
Objects.requireNonNull(name);
if (!name.startsWith("nashorn.")) {
throw new IllegalArgumentException(name);
}
checkPropertyName(name);
return AccessController.doPrivileged(
new PrivilegedAction<Boolean>() {
@Override
@ -185,11 +187,7 @@ public final class Options {
* @return string property if set or default value
*/
public static String getStringProperty(final String name, final String defValue) {
Objects.requireNonNull(name);
if (! name.startsWith("nashorn.")) {
throw new IllegalArgumentException(name);
}
checkPropertyName(name);
return AccessController.doPrivileged(
new PrivilegedAction<String>() {
@Override
@ -212,11 +210,7 @@ public final class Options {
* @return integer property if set or default value
*/
public static int getIntProperty(final String name, final int defValue) {
Objects.requireNonNull(name);
if (! name.startsWith("nashorn.")) {
throw new IllegalArgumentException(name);
}
checkPropertyName(name);
return AccessController.doPrivileged(
new PrivilegedAction<Integer>() {
@Override

View File

@ -229,6 +229,11 @@ public final class EncodingHelper {
/**
* @see <a href="http://www.geocities.jp/kosako3/oniguruma/doc/RE.txt">http://www.geocities.jp/kosako3/oniguruma/doc/RE.txt</a>
*
* @param code code
* @param ctype ctype
*
* @return isCodeCType
*/
public static boolean isCodeCType(final int code, final int ctype) {
int type;

View File

@ -57,10 +57,10 @@ public final class Syntax implements SyntaxProperties {
}
}
/**
* OP
*
*/
//
// OP
//
protected boolean isOp(final int opm) {
return (op & opm) != 0;
}
@ -189,11 +189,10 @@ public final class Syntax implements SyntaxProperties {
return isOp(OP_ESC_X_BRACE_HEX8);
}
//
// OP2
//
/**
* OP
*
*/
protected boolean isOp2(final int opm) {
return (op2 & opm) != 0;
}
@ -278,10 +277,10 @@ public final class Syntax implements SyntaxProperties {
return isOp2(OP2_INEFFECTIVE_ESCAPE);
}
/**
* BEHAVIOR
*
*/
//
// BEHAVIOR
//
protected boolean isBehavior(final int bvm) {
return (behavior & bvm) != 0;
}

View File

@ -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-8085802: Nashorn -nse option causes parse error on anonymous function definition
*
* @test
* @run
* @option -nse
*/
// even with -nse passed, the following should run fine
// because anonymous function is used as expression here
(function (){})()

View File

@ -0,0 +1,31 @@
/*
* 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.
*/
/**
* Anonymous function statement should result in error in -nse
*
* @option -nse
* @test/compile-error
*/
function() {}

View File

@ -0,0 +1,3 @@
test/script/error/anon_func_stat_nse.js:31:8 Expected ident but found (
function() {}
^

View File

@ -0,0 +1,32 @@
/*
* 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.
*/
/**
* Backquote string should result in error with -nse even with -scripting
*
* @option -nse
* @option -scripting
* @test/compile-error
*/
`ls -l`;

View File

@ -0,0 +1,3 @@
test/script/error/backquote_string_nse.js:32:0 Expected an operand but found error
`ls -l`;
^

View File

@ -0,0 +1,34 @@
/*
* 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.
*/
/**
* conditional catch should result in error with -nse
*
* @option -nse
* @test/compile-error
*/
try {
func();
} catch (e if e instanceof ReferenceError) {
}

View File

@ -0,0 +1,6 @@
test/script/error/conditional_catch_nse.js:33:11 Expected ) but found if
} catch (e if e instanceof ReferenceError) {
^
test/script/error/conditional_catch_nse.js:34:0 Expected eof but found }
}
^

View File

@ -0,0 +1,31 @@
/*
* 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.
*/
/**
* Expression closures should result in error with -nse
*
* @option -nse
* @test/compile-error
*/
function square(x) x*x;

View File

@ -0,0 +1,3 @@
test/script/error/expr_closure_nse.js:31:19 Expected { but found x
function square(x) x*x;
^

View File

@ -0,0 +1,33 @@
/*
* 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.
*/
/**
* for..each should result in error with -nse
*
* @option -nse
* @test/compile-error
*/
for each (var x in [3, 454, 4]) {
print(x);
}

View File

@ -0,0 +1,6 @@
test/script/error/for_each_nse.js:31:4 Expected ( but found each
for each (var x in [3, 454, 4]) {
^
test/script/error/for_each_nse.js:33:0 Expected eof but found }
}
^

View File

@ -0,0 +1,32 @@
/*
* 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.
*/
/**
* Hash comment should result in error with -nse even with -scripting
*
* @option -nse
* @option -scripting
* @test/compile-error
*/
# this is a comment

View File

@ -0,0 +1,3 @@
test/script/error/hash_comment_nse.js:32:0 Expected an operand but found error
# this is a comment
^

View File

@ -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.
*/
/**
* Heredoc string should result in error with -nse even with -scripting
*
* @option -nse
* @option -scripting
* @test/compile-error
*/
var str = <<EOF
This is a multiple line string
inside a heredoc
EOF;

View File

@ -0,0 +1,9 @@
test/script/error/heredoc_nse.js:32:10 Expected an operand but found <<
var str = <<EOF
^
test/script/error/heredoc_nse.js:33:5 Expected ; but found is
This is a multiple line string
^
test/script/error/heredoc_nse.js:34:7 Expected ; but found a
inside a heredoc
^

View File

@ -0,0 +1,33 @@
/*
* 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.
*/
/**
* Object literal outside 'new' should result in error in -nse
*
* @option -nse
* @test/compile-error
*/
var r = new java.lang.Runnable() {
run: function() { print("hello"); }
}

View File

@ -0,0 +1,9 @@
test/script/error/object_literal_in_new_nse.js:31:33 Expected ; but found {
var r = new java.lang.Runnable() {
^
test/script/error/object_literal_in_new_nse.js:32:15 Expected ident but found (
run: function() { print("hello"); }
^
test/script/error/object_literal_in_new_nse.js:32:36 Expected eof but found }
run: function() { print("hello"); }
^

View File

@ -0,0 +1,38 @@
/*
* 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-8080087: Nashorn $ENV.PWD is originally undefined
*
* This is to ensure that $ENV.PWD is correctly set on Windows as well as on all
* other platforms.
*
* @test
* @option -scripting
* @run
*/
if (typeof($ENV.PWD) === 'undefined') {
fail('$ENV.PWD is undefined')
}