diff options
Diffstat (limited to 'src/jdk/nashorn/api/scripting/NashornScriptEngine.java')
-rw-r--r-- | src/jdk/nashorn/api/scripting/NashornScriptEngine.java | 165 |
1 files changed, 17 insertions, 148 deletions
diff --git a/src/jdk/nashorn/api/scripting/NashornScriptEngine.java b/src/jdk/nashorn/api/scripting/NashornScriptEngine.java index 7ebe5c91..2f000954 100644 --- a/src/jdk/nashorn/api/scripting/NashornScriptEngine.java +++ b/src/jdk/nashorn/api/scripting/NashornScriptEngine.java @@ -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,12 +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" }; // Nashorn script engine error message management private static final String MESSAGES_RESOURCE = "jdk.nashorn.api.scripting.resources.Messages"; @@ -122,36 +110,8 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C } } - // load engine.js - @SuppressWarnings("resource") - 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); - } - - NashornScriptEngine(final NashornScriptEngineFactory factory, final String[] args, final ClassLoader appLoader) { + NashornScriptEngine(final NashornScriptEngineFactory factory, final String[] args, final ClassLoader appLoader, final ClassFilter classFilter) { + assert args != null : "null argument array"; this.factory = factory; final Options options = new Options("nashorn"); options.process(args); @@ -163,7 +123,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C @Override public Context run() { try { - return new Context(options, errMgr, appLoader); + return new Context(options, errMgr, appLoader, classFilter); } catch (final RuntimeException e) { if (Context.DEBUG) { e.printStackTrace(); @@ -249,39 +209,12 @@ 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 { try { return sourceFor(getScriptName(ctxt), reader); - } catch (IOException e) { + } catch (final IOException e) { throw new ScriptException(e); } } @@ -296,6 +229,8 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C } private <T> T getInterfaceInner(final Object thiz, final Class<T> clazz) { + assert !(thiz instanceof ScriptObject) : "raw ScriptObject not expected here"; + if (clazz == null || !clazz.isInterface()) { throw new IllegalArgumentException(getMessage("interface.class.expected")); } @@ -321,17 +256,6 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C if (! isOfContext(realGlobal, nashornContext)) { throw new IllegalArgumentException(getMessage("script.object.from.another.engine")); } - } else if (thiz instanceof ScriptObject) { - // called from script code. - realSelf = (ScriptObject)thiz; - realGlobal = Context.getGlobal(); - if (realGlobal == null) { - throw new IllegalArgumentException(getMessage("no.current.nashorn.global")); - } - - if (! isOfContext(realGlobal, nashornContext)) { - throw new IllegalArgumentException(getMessage("script.object.from.another.engine")); - } } if (realSelf == null) { @@ -380,7 +304,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C } // Arbitrary user Bindings implementation. Look for NASHORN_GLOBAL in it! - Object scope = bindings.get(NASHORN_GLOBAL); + final Object scope = bindings.get(NASHORN_GLOBAL); if (scope instanceof ScriptObjectMirror) { final Global glob = globalFromMirror((ScriptObjectMirror)scope); if (glob != null) { @@ -397,7 +321,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C // Retrieve nashorn Global object from a given ScriptObjectMirror private Global globalFromMirror(final ScriptObjectMirror mirror) { - ScriptObject sobj = mirror.getScriptObject(); + final ScriptObject sobj = mirror.getScriptObject(); if (sobj instanceof Global && isOfContext((Global)sobj, nashornContext)) { return (Global)sobj; } @@ -427,49 +351,15 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C } }, CREATE_GLOBAL_ACC_CTXT); - nashornContext.initGlobal(newGlobal); - - 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; - } + nashornContext.initGlobal(newGlobal, this); + newGlobal.setScriptContext(ctxt); - // 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.setObjectValue(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); - } + return newGlobal; } private Object invokeImpl(final Object selfObject, final String name, final Object... args) throws ScriptException, NoSuchMethodException { name.getClass(); // null check + assert !(selfObject instanceof ScriptObject) : "raw ScriptObject not expected here"; Global invokeGlobal = null; ScriptObjectMirror selfMirror = null; @@ -479,20 +369,6 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C throw new IllegalArgumentException(getMessage("script.object.from.another.engine")); } invokeGlobal = selfMirror.getHomeGlobal(); - } else if (selfObject instanceof ScriptObject) { - // invokeMethod called from script code - in which case we may get 'naked' ScriptObject - // Wrap it with oldGlobal to make a ScriptObjectMirror for the same. - final Global oldGlobal = Context.getGlobal(); - invokeGlobal = oldGlobal; - if (oldGlobal == null) { - throw new IllegalArgumentException(getMessage("no.current.nashorn.global")); - } - - if (! isOfContext(oldGlobal, nashornContext)) { - throw new IllegalArgumentException(getMessage("script.object.from.another.engine")); - } - - selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(selfObject, oldGlobal); } else if (selfObject == null) { // selfObject is null => global function call final Global ctxtGlobal = getNashornGlobalFrom(context); @@ -525,7 +401,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C return evalImpl(script, ctxt, getNashornGlobalFrom(ctxt)); } - private Object evalImpl(final Context.MultiGlobalCompiledScript mgcs, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException { + private static Object evalImpl(final Context.MultiGlobalCompiledScript mgcs, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException { final Global oldGlobal = Context.getGlobal(); final boolean globalChanged = (oldGlobal != ctxtGlobal); try { @@ -534,11 +410,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); @@ -550,7 +422,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C } } - private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException { + private static Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException { if (script == null) { return null; } @@ -561,10 +433,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); @@ -671,7 +540,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C continue; } - Object obj = sobj.get(method.getName()); + final Object obj = sobj.get(method.getName()); if (! (obj instanceof ScriptFunction)) { return false; } |