Merge
This commit is contained in:
commit
a0d63f0bf4
151
nashorn/samples/autoimports.js
Normal file
151
nashorn/samples/autoimports.js
Normal 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);
|
||||
}
|
||||
}
|
||||
})();
|
73
nashorn/samples/dateconversion.js
Normal file
73
nashorn/samples/dateconversion.js
Normal 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
50
nashorn/samples/exec.js
Normal 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"]));
|
67
nashorn/samples/javahelp.js
Normal file
67
nashorn/samples/javahelp.js
Normal 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;
|
43
nashorn/samples/secondssince.js
Normal file
43
nashorn/samples/secondssince.js
Normal 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);
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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>() {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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"));
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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--) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 "";
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
35
nashorn/test/script/basic/JDK-8085802.js
Normal file
35
nashorn/test/script/basic/JDK-8085802.js
Normal 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 (){})()
|
31
nashorn/test/script/error/anon_func_stat_nse.js
Normal file
31
nashorn/test/script/error/anon_func_stat_nse.js
Normal 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() {}
|
3
nashorn/test/script/error/anon_func_stat_nse.js.EXPECTED
Normal file
3
nashorn/test/script/error/anon_func_stat_nse.js.EXPECTED
Normal file
@ -0,0 +1,3 @@
|
||||
test/script/error/anon_func_stat_nse.js:31:8 Expected ident but found (
|
||||
function() {}
|
||||
^
|
32
nashorn/test/script/error/backquote_string_nse.js
Normal file
32
nashorn/test/script/error/backquote_string_nse.js
Normal 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`;
|
@ -0,0 +1,3 @@
|
||||
test/script/error/backquote_string_nse.js:32:0 Expected an operand but found error
|
||||
`ls -l`;
|
||||
^
|
34
nashorn/test/script/error/conditional_catch_nse.js
Normal file
34
nashorn/test/script/error/conditional_catch_nse.js
Normal 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) {
|
||||
}
|
@ -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 }
|
||||
}
|
||||
^
|
31
nashorn/test/script/error/expr_closure_nse.js
Normal file
31
nashorn/test/script/error/expr_closure_nse.js
Normal 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;
|
3
nashorn/test/script/error/expr_closure_nse.js.EXPECTED
Normal file
3
nashorn/test/script/error/expr_closure_nse.js.EXPECTED
Normal file
@ -0,0 +1,3 @@
|
||||
test/script/error/expr_closure_nse.js:31:19 Expected { but found x
|
||||
function square(x) x*x;
|
||||
^
|
33
nashorn/test/script/error/for_each_nse.js
Normal file
33
nashorn/test/script/error/for_each_nse.js
Normal 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);
|
||||
}
|
6
nashorn/test/script/error/for_each_nse.js.EXPECTED
Normal file
6
nashorn/test/script/error/for_each_nse.js.EXPECTED
Normal 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 }
|
||||
}
|
||||
^
|
32
nashorn/test/script/error/hash_comment_nse.js
Normal file
32
nashorn/test/script/error/hash_comment_nse.js
Normal 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
|
3
nashorn/test/script/error/hash_comment_nse.js.EXPECTED
Normal file
3
nashorn/test/script/error/hash_comment_nse.js.EXPECTED
Normal file
@ -0,0 +1,3 @@
|
||||
test/script/error/hash_comment_nse.js:32:0 Expected an operand but found error
|
||||
# this is a comment
|
||||
^
|
35
nashorn/test/script/error/heredoc_nse.js
Normal file
35
nashorn/test/script/error/heredoc_nse.js
Normal 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;
|
9
nashorn/test/script/error/heredoc_nse.js.EXPECTED
Normal file
9
nashorn/test/script/error/heredoc_nse.js.EXPECTED
Normal 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
|
||||
^
|
33
nashorn/test/script/error/object_literal_in_new_nse.js
Normal file
33
nashorn/test/script/error/object_literal_in_new_nse.js
Normal 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"); }
|
||||
}
|
@ -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"); }
|
||||
^
|
38
nashorn/test/script/nosecurity/JDK-8080087.js
Normal file
38
nashorn/test/script/nosecurity/JDK-8080087.js
Normal 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')
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user