8049524: Global object initialization via javax.script API should be minimal

Reviewed-by: attila, hannesw
This commit is contained in:
Athijegannathan Sundararajan 2014-07-08 16:30:42 +05:30
parent 8159b11738
commit 4048ec18f3
9 changed files with 125 additions and 251 deletions

View File

@ -53,9 +53,6 @@ public abstract class NashornException extends RuntimeException {
// underlying ECMA error object - lazily initialized
private Object ecmaError;
/** script source name used for "engine.js" */
public static final String ENGINE_SCRIPT_SOURCE_NAME = "nashorn:engine/resources/engine.js";
/**
* Constructor
*

View File

@ -25,8 +25,6 @@
package jdk.nashorn.api.scripting;
import static jdk.nashorn.internal.runtime.ECMAErrors.referenceError;
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
import static jdk.nashorn.internal.runtime.Source.sourceFor;
import java.io.IOException;
@ -34,13 +32,10 @@ import java.io.Reader;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.Permissions;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.security.ProtectionDomain;
import java.text.MessageFormat;
import java.util.Locale;
@ -58,7 +53,6 @@ import javax.script.SimpleBindings;
import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.ErrorManager;
import jdk.nashorn.internal.runtime.Property;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;
@ -98,9 +92,6 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
// This is the initial default Nashorn global object.
// This is used as "shared" global if above option is true.
private final Global global;
// initialized bit late to be made 'final'.
// Property object for "context" property of global object.
private volatile Property contextProperty;
// default options passed to Nashorn Options object
private static final String[] DEFAULT_OPTIONS = new String[] { "-doe" };
@ -122,30 +113,6 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
}
}
// load engine.js
private static Source loadEngineJSSource() {
final String script = "resources/engine.js";
try {
return AccessController.doPrivileged(
new PrivilegedExceptionAction<Source>() {
@Override
public Source run() throws IOException {
final URL url = NashornScriptEngine.class.getResource(script);
return sourceFor(NashornException.ENGINE_SCRIPT_SOURCE_NAME, url);
}
}
);
} catch (final PrivilegedActionException e) {
if (Context.DEBUG) {
e.printStackTrace();
}
throw new RuntimeException(e);
}
}
// Source object for engine.js
private static final Source ENGINE_SCRIPT_SRC = loadEngineJSSource();
NashornScriptEngine(final NashornScriptEngineFactory factory, final ClassLoader appLoader) {
this(factory, DEFAULT_OPTIONS, appLoader);
}
@ -248,33 +215,6 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
return getInterfaceInner(thiz, clazz);
}
// These are called from the "engine.js" script
/**
* This hook is used to search js global variables exposed from Java code.
*
* @param self 'this' passed from the script
* @param ctxt current ScriptContext in which name is searched
* @param name name of the variable searched
* @return the value of the named variable
*/
public Object __noSuchProperty__(final Object self, final ScriptContext ctxt, final String name) {
if (ctxt != null) {
final int scope = ctxt.getAttributesScope(name);
final Global ctxtGlobal = getNashornGlobalFrom(ctxt);
if (scope != -1) {
return ScriptObjectMirror.unwrap(ctxt.getAttribute(name, scope), ctxtGlobal);
}
if (self == UNDEFINED) {
// scope access and so throw ReferenceError
throw referenceError(ctxtGlobal, "not.defined", name);
}
}
return UNDEFINED;
}
// Implementation only below this point
private static Source makeSource(final Reader reader, final ScriptContext ctxt) throws ScriptException {
@ -426,47 +366,12 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
}
}, CREATE_GLOBAL_ACC_CTXT);
nashornContext.initGlobal(newGlobal);
nashornContext.initGlobal(newGlobal, this);
newGlobal.setScriptContext(ctxt);
final int NON_ENUMERABLE_CONSTANT = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE;
// current ScriptContext exposed as "context"
// "context" is non-writable from script - but script engine still
// needs to set it and so save the context Property object
contextProperty = newGlobal.addOwnProperty("context", NON_ENUMERABLE_CONSTANT, ctxt);
// current ScriptEngine instance exposed as "engine". We added @SuppressWarnings("LeakingThisInConstructor") as
// NetBeans identifies this assignment as such a leak - this is a false positive as we're setting this property
// in the Global of a Context we just created - both the Context and the Global were just created and can not be
// seen from another thread outside of this constructor.
newGlobal.addOwnProperty("engine", NON_ENUMERABLE_CONSTANT, this);
// global script arguments with undefined value
newGlobal.addOwnProperty("arguments", Property.NOT_ENUMERABLE, UNDEFINED);
// file name default is null
newGlobal.addOwnProperty(ScriptEngine.FILENAME, Property.NOT_ENUMERABLE, null);
// evaluate engine.js initialization script this new global object
try {
evalImpl(compileImpl(ENGINE_SCRIPT_SRC, newGlobal), ctxt, newGlobal);
} catch (final ScriptException exp) {
throw new RuntimeException(exp);
}
return newGlobal;
}
// scripts should see "context" and "engine" as variables in the given global object
private void setContextVariables(final Global ctxtGlobal, final ScriptContext ctxt) {
// set "context" global variable via contextProperty - because this
// property is non-writable
contextProperty.setValue(ctxtGlobal, ctxtGlobal, ctxt, false);
Object args = ScriptObjectMirror.unwrap(ctxt.getAttribute("arguments"), ctxtGlobal);
if (args == null || args == UNDEFINED) {
args = ScriptRuntime.EMPTY_ARRAY;
}
// if no arguments passed, expose it
if (! (args instanceof ScriptObject)) {
args = ctxtGlobal.wrapAsObject(args);
ctxtGlobal.set("arguments", args, false);
}
}
private Object invokeImpl(final Object selfObject, final String name, final Object... args) throws ScriptException, NoSuchMethodException {
name.getClass(); // null check
@ -533,11 +438,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
}
final ScriptFunction script = mgcs.getFunction(ctxtGlobal);
// set ScriptContext variables if ctxt is non-null
if (ctxt != null) {
setContextVariables(ctxtGlobal, ctxt);
}
ctxtGlobal.setScriptContext(ctxt);
return ScriptObjectMirror.translateUndefined(ScriptObjectMirror.wrap(ScriptRuntime.apply(script, ctxtGlobal), ctxtGlobal));
} catch (final Exception e) {
throwAsScriptException(e, ctxtGlobal);
@ -560,10 +461,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
Context.setGlobal(ctxtGlobal);
}
// set ScriptContext variables if ctxt is non-null
if (ctxt != null) {
setContextVariables(ctxtGlobal, ctxt);
}
ctxtGlobal.setScriptContext(ctxt);
return ScriptObjectMirror.translateUndefined(ScriptObjectMirror.wrap(ScriptRuntime.apply(script, ctxtGlobal), ctxtGlobal));
} catch (final Exception e) {
throwAsScriptException(e, ctxtGlobal);

View File

@ -1,101 +0,0 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* This script file is executed by script engine at the construction
* of the every new Global object. The functions here assume global variables
* "context" of type javax.script.ScriptContext and "engine" of the type
* jdk.nashorn.api.scripting.NashornScriptEngine.
**/
Object.defineProperty(this, "__noSuchProperty__", {
configurable: true,
enumerable: false,
writable: true,
value: function (name) {
'use strict';
return engine.__noSuchProperty__(this, context, name);
}
});
function print() {
var writer = context != null? context.writer : engine.context.writer;
if (! (writer instanceof java.io.PrintWriter)) {
writer = new java.io.PrintWriter(writer);
}
var buf = new java.lang.StringBuilder();
for (var i = 0; i < arguments.length; i++) {
if (i != 0) {
buf.append(' ');
}
buf.append(String(arguments[i]));
}
writer.println(buf.toString());
}
/**
* This is C-like printf
*
* @param format string to format the rest of the print items
* @param args variadic argument list
*/
Object.defineProperty(this, "printf", {
configurable: true,
enumerable: false,
writable: true,
value: function (format, args/*, more args*/) {
print(sprintf.apply(this, arguments));
}
});
/**
* This is C-like sprintf
*
* @param format string to format the rest of the print items
* @param args variadic argument list
*/
Object.defineProperty(this, "sprintf", {
configurable: true,
enumerable: false,
writable: true,
value: function (format, args/*, more args*/) {
var len = arguments.length - 1;
var array = [];
if (len < 0) {
return "";
}
for (var i = 0; i < len; i++) {
if (arguments[i+1] instanceof Date) {
array[i] = arguments[i+1].getTime();
} else {
array[i] = arguments[i+1];
}
}
array = Java.to(array);
return Packages.jdk.nashorn.api.scripting.ScriptUtils.format(format, array);
}
});

View File

@ -27,6 +27,7 @@ package jdk.nashorn.internal.objects;
import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
import static jdk.nashorn.internal.lookup.Lookup.MH;
import static jdk.nashorn.internal.runtime.ECMAErrors.referenceError;
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
@ -45,8 +46,11 @@ import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkRequest;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
import jdk.nashorn.internal.codegen.ApplySpecialization;
import jdk.nashorn.internal.codegen.CompilerConstants.Call;
import jdk.nashorn.internal.lookup.Lookup;
@ -107,6 +111,10 @@ public final class Global extends ScriptObject implements Scope {
/** Name invalidator for things like call/apply */
public static final Call BOOTSTRAP = staticCall(MethodHandles.lookup(), Global.class, "invalidateNameBootstrap", CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
/** Nashorn extension: arguments array */
@Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE)
public Object arguments;
/** ECMA 15.1.2.2 parseInt (string , radix) */
@Property(attributes = Attribute.NOT_ENUMERABLE)
public Object parseInt;
@ -411,12 +419,13 @@ public final class Global extends ScriptObject implements Scope {
// Used to store the last RegExp result to support deprecated RegExp constructor properties
private RegExpResult lastRegExpResult;
private static final MethodHandle EVAL = findOwnMH_S("eval", Object.class, Object.class, Object.class);
private static final MethodHandle PRINT = findOwnMH_S("print", Object.class, Object.class, Object[].class);
private static final MethodHandle PRINTLN = findOwnMH_S("println", Object.class, Object.class, Object[].class);
private static final MethodHandle LOAD = findOwnMH_S("load", Object.class, Object.class, Object.class);
private static final MethodHandle LOADWITHNEWGLOBAL = findOwnMH_S("loadWithNewGlobal", Object.class, Object.class, Object[].class);
private static final MethodHandle EXIT = findOwnMH_S("exit", Object.class, Object.class, Object.class);
private static final MethodHandle EVAL = findOwnMH_S("eval", Object.class, Object.class, Object.class);
private static final MethodHandle NO_SUCH_PROPERTY = findOwnMH_S(NO_SUCH_PROPERTY_NAME, Object.class, Object.class, Object.class);
private static final MethodHandle PRINT = findOwnMH_S("print", Object.class, Object.class, Object[].class);
private static final MethodHandle PRINTLN = findOwnMH_S("println", Object.class, Object.class, Object[].class);
private static final MethodHandle LOAD = findOwnMH_S("load", Object.class, Object.class, Object.class);
private static final MethodHandle LOADWITHNEWGLOBAL = findOwnMH_S("loadWithNewGlobal", Object.class, Object.class, Object[].class);
private static final MethodHandle EXIT = findOwnMH_S("exit", Object.class, Object.class, Object.class);
/** Invalidate a reserved name, such as "apply" or "call" if assigned */
public MethodHandle INVALIDATE_RESERVED_NAME = MH.bindTo(findOwnMH_V("invalidateReservedName", void.class, String.class), this);
@ -427,6 +436,20 @@ public final class Global extends ScriptObject implements Scope {
// context to which this global belongs to
private final Context context;
// current ScriptContext to use - can be null.
private ScriptContext scontext;
// associated Property object for "context" property.
private jdk.nashorn.internal.runtime.Property scontextProperty;
/**
* Set the current script context
* @param scontext script context
*/
public void setScriptContext(final ScriptContext scontext) {
this.scontext = scontext;
scontextProperty.setValue(this, this, scontext, false);
}
// global constants for this global - they can be replaced with MethodHandle.constant until invalidated
private static AtomicReference<GlobalConstants> gcsInstance = new AtomicReference<>();
@ -478,6 +501,10 @@ public final class Global extends ScriptObject implements Scope {
return global;
}
private static Global instanceFrom(final Object self) {
return self instanceof Global? (Global)self : instance();
}
/**
* Return the global constants map for fields that
* can be accessed as MethodHandle.constant
@ -537,13 +564,13 @@ public final class Global extends ScriptObject implements Scope {
* as well as our extension builtin objects like "Java", "JSAdapter" as properties
* of the global scope object.
*/
public void initBuiltinObjects() {
public void initBuiltinObjects(final ScriptEngine engine) {
if (this.builtinObject != null) {
// already initialized, just return
return;
}
init();
init(engine);
}
/**
@ -843,6 +870,32 @@ public final class Global extends ScriptObject implements Scope {
return getLazilyCreatedValue(key, creator, dynamicInvokers);
}
/**
* Hook to search missing variables in ScriptContext if available
* @param self used to detect if scope call or not (this function is 'strict')
* @param name name of the variable missing
* @return value of the missing variable or undefined (or TypeError for scope search)
*/
public static Object __noSuchProperty__(final Object self, final Object name) {
final Global global = Global.instance();
final ScriptContext sctxt = global.scontext;
final String nameStr = name.toString();
if (sctxt != null) {
final int scope = sctxt.getAttributesScope(nameStr);
if (scope != -1) {
return ScriptObjectMirror.unwrap(sctxt.getAttribute(nameStr, scope), global);
}
}
if (self == UNDEFINED) {
// scope access and so throw ReferenceError
throw referenceError(global, "not.defined", nameStr);
}
return UNDEFINED;
}
/**
* This is the eval used when 'indirect' eval call is made.
*
@ -875,7 +928,7 @@ public final class Global extends ScriptObject implements Scope {
if (!(str instanceof String || str instanceof ConsString)) {
return str;
}
final Global global = Global.instance();
final Global global = Global.instanceFrom(self);
final ScriptObject scope = self instanceof ScriptObject ? (ScriptObject)self : global;
return global.getContext().eval(scope, str.toString(), callThis, location, Boolean.TRUE.equals(strict), true);
@ -890,7 +943,7 @@ public final class Global extends ScriptObject implements Scope {
* @return result of print (undefined)
*/
public static Object print(final Object self, final Object... objects) {
return printImpl(false, objects);
return Global.instanceFrom(self).printImpl(false, objects);
}
/**
@ -902,7 +955,7 @@ public final class Global extends ScriptObject implements Scope {
* @return result of println (undefined)
*/
public static Object println(final Object self, final Object... objects) {
return printImpl(true, objects);
return Global.instanceFrom(self).printImpl(true, objects);
}
/**
@ -916,7 +969,7 @@ public final class Global extends ScriptObject implements Scope {
* @throws IOException if source could not be read
*/
public static Object load(final Object self, final Object source) throws IOException {
final Global global = Global.instance();
final Global global = Global.instanceFrom(self);
final ScriptObject scope = self instanceof ScriptObject ? (ScriptObject)self : global;
return global.getContext().load(scope, source);
}
@ -932,7 +985,7 @@ public final class Global extends ScriptObject implements Scope {
* @throws IOException if source could not be read
*/
public static Object loadWithNewGlobal(final Object self, final Object...args) throws IOException {
final Global global = Global.instance();
final Global global = Global.instanceFrom(self);
final int length = args.length;
final boolean hasArgs = 0 < length;
final Object from = hasArgs ? args[0] : UNDEFINED;
@ -1599,7 +1652,7 @@ public final class Global extends ScriptObject implements Scope {
splitState = state;
}
private void init() {
private void init(final ScriptEngine engine) {
assert Context.getGlobal() == this : "this global is not set as current";
final ScriptEnvironment env = getContext().getEnv();
@ -1700,12 +1753,19 @@ public final class Global extends ScriptObject implements Scope {
copyBuiltins();
// expose script (command line) arguments as "arguments" property of global
final Object argumentsObject = wrapAsObject(env.getArguments().toArray());
final int argumentsFlags = Attribute.NOT_ENUMERABLE;
addOwnProperty("arguments", argumentsFlags, argumentsObject);
arguments = wrapAsObject(env.getArguments().toArray());
if (env._scripting) {
// synonym for "arguments" in scripting mode
addOwnProperty("$ARG", argumentsFlags, argumentsObject);
addOwnProperty("$ARG", Attribute.NOT_ENUMERABLE, arguments);
}
if (engine != null) {
final int NOT_ENUMERABLE_NOT_CONFIG = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE;
scontextProperty = addOwnProperty("context", NOT_ENUMERABLE_NOT_CONFIG, null);
addOwnProperty("engine", NOT_ENUMERABLE_NOT_CONFIG, engine);
// __noSuchProperty__ hook for ScriptContext search of missing variables
final ScriptFunction noSuchProp = ScriptFunctionImpl.makeStrictFunction(NO_SUCH_PROPERTY_NAME, NO_SUCH_PROPERTY);
addOwnProperty(NO_SUCH_PROPERTY_NAME, Attribute.NOT_ENUMERABLE, noSuchProp);
}
}
@ -1873,8 +1933,8 @@ public final class Global extends ScriptObject implements Scope {
this.addOwnProperty("Debug", Attribute.NOT_ENUMERABLE, initConstructor("Debug"));
}
private static Object printImpl(final boolean newLine, final Object... objects) {
final PrintWriter out = Global.getEnv().getOut();
private Object printImpl(final boolean newLine, final Object... objects) {
final PrintWriter out = scontext != null? new PrintWriter(scontext.getWriter()) : getContext().getEnv().getOut();
final StringBuilder sb = new StringBuilder();
for (final Object object : objects) {
@ -2018,12 +2078,11 @@ public final class Global extends ScriptObject implements Scope {
for (final jdk.nashorn.internal.runtime.Property property : properties) {
final Object key = property.getKey();
final Object value = ObjectPrototype.get(key);
if (key.equals("constructor")) {
continue;
}
final Object value = ObjectPrototype.get(key);
if (value instanceof ScriptFunction) {
final ScriptFunction func = (ScriptFunction)value;
final ScriptObject prototype = ScriptFunction.getPrototype(func);

View File

@ -184,6 +184,15 @@ public class ScriptFunctionImpl extends ScriptFunction {
return new AnonymousFunction();
}
private static ScriptFunction makeFunction(final String name, final MethodHandle methodHandle, final MethodHandle[] specs, final int flags) {
final ScriptFunctionImpl func = new ScriptFunctionImpl(name, methodHandle, null, specs, flags);
func.setPrototype(UNDEFINED);
// Non-constructor built-in functions do not have "prototype" property
func.deleteOwnProperty(func.getMap().findProperty("prototype"));
return func;
}
/**
* Factory method for non-constructor built-in functions
*
@ -193,12 +202,18 @@ public class ScriptFunctionImpl extends ScriptFunction {
* @return new ScriptFunction
*/
static ScriptFunction makeFunction(final String name, final MethodHandle methodHandle, final MethodHandle[] specs) {
final ScriptFunctionImpl func = new ScriptFunctionImpl(name, methodHandle, null, specs, ScriptFunctionData.IS_BUILTIN);
func.setPrototype(UNDEFINED);
// Non-constructor built-in functions do not have "prototype" property
func.deleteOwnProperty(func.getMap().findProperty("prototype"));
return makeFunction(name, methodHandle, specs, ScriptFunctionData.IS_BUILTIN);
}
return func;
/**
* Factory method for non-constructor built-in, strict functions
*
* @param name function name
* @param methodHandle handle for invocation
* @return new ScriptFunction
*/
static ScriptFunction makeStrictFunction(final String name, final MethodHandle methodHandle) {
return makeFunction(name, methodHandle, null, ScriptFunctionData.IS_BUILTIN | ScriptFunctionData.IS_STRICT );
}
/**

View File

@ -62,6 +62,7 @@ import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.logging.Level;
import javax.script.ScriptEngine;
import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.util.CheckClassAdapter;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
@ -954,16 +955,17 @@ public final class Context {
* Initialize given global scope object.
*
* @param global the global
* @param engine the associated ScriptEngine instance, can be null
* @return the initialized global scope object.
*/
public Global initGlobal(final Global global) {
public Global initGlobal(final Global global, final ScriptEngine engine) {
// Need only minimal global object, if we are just compiling.
if (!env._compile_only) {
final Global oldGlobal = Context.getGlobal();
try {
Context.setGlobal(global);
// initialize global scope with builtin global objects
global.initBuiltinObjects();
global.initBuiltinObjects(engine);
} finally {
Context.setGlobal(oldGlobal);
}
@ -972,6 +974,16 @@ public final class Context {
return global;
}
/**
* Initialize given global scope object.
*
* @param global the global
* @return the initialized global scope object.
*/
public Global initGlobal(final Global global) {
return initGlobal(global, null);
}
/**
* Return the current global's context
* @return current global's context

View File

@ -405,12 +405,8 @@ public final class ECMAErrors {
// Look for script package in class name (into which compiler puts generated code)
if (className.startsWith(scriptPackage) && !CompilerConstants.isInternalMethodName(frame.getMethodName())) {
final String source = frame.getFileName();
/*
* Make sure that it is not some Java code that Nashorn has in that package!
* also, we don't want to report JavaScript code that lives in script engine implementation
* We want to report only user's own scripts and not any of our own scripts like "engine.js"
*/
return source != null && !source.endsWith(".java") && !source.contains(NashornException.ENGINE_SCRIPT_SOURCE_NAME);
// Make sure that it is not some Java code that Nashorn has in that package!
return source != null && !source.endsWith(".java");
}
return false;
}

View File

@ -103,10 +103,10 @@ public abstract class ScriptObject implements PropertyAccess {
public static final String PROTO_PROPERTY_NAME = "__proto__";
/** Search fall back routine name for "no such method" */
static final String NO_SUCH_METHOD_NAME = "__noSuchMethod__";
public static final String NO_SUCH_METHOD_NAME = "__noSuchMethod__";
/** Search fall back routine name for "no such property" */
static final String NO_SUCH_PROPERTY_NAME = "__noSuchProperty__";
public static final String NO_SUCH_PROPERTY_NAME = "__noSuchProperty__";
/** Per ScriptObject flag - is this a scope object? */
public static final int IS_SCOPE = 1 << 0;

View File

@ -136,8 +136,7 @@ public class CodeStoreAndPathTest {
// Check that a new compiled script is stored in existing code cache
e.eval(code1);
final DirectoryStream<Path> stream = Files.newDirectoryStream(codeCachePath);
// Already one compiled script has been stored in the cache during initialization
checkCompiledScripts(stream, 2);
checkCompiledScripts(stream, 1);
// Setting to default current working dir
} finally {
System.setProperty("user.dir", oldUserDir);
@ -154,9 +153,8 @@ public class CodeStoreAndPathTest {
e.eval(code1);
e.eval(code2);
e.eval(code3);// less than minimum size for storing
// Already one compiled script has been stored in the cache during initialization
// adding code1 and code2.
final DirectoryStream<Path> stream = Files.newDirectoryStream(codeCachePath);
checkCompiledScripts(stream, 3);
checkCompiledScripts(stream, 2);
}
}