src/jdk/nashorn/api/scripting/NashornScriptEngine.java
Print this page
*** 55,67 ****
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptException;
import javax.script.SimpleBindings;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.ErrorManager;
- import jdk.nashorn.internal.runtime.GlobalObject;
import jdk.nashorn.internal.runtime.Property;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;
import jdk.nashorn.internal.runtime.Source;
--- 55,67 ----
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptException;
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;
import jdk.nashorn.internal.runtime.Source;
*** 97,107 ****
private final Context nashornContext;
// do we want to share single Nashorn global instance across ENGINE_SCOPEs?
private final boolean _global_per_engine;
// This is the initial default Nashorn global object.
// This is used as "shared" global if above option is true.
! private final ScriptObject 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
--- 97,107 ----
private final Context nashornContext;
// do we want to share single Nashorn global instance across ENGINE_SCOPEs?
private final boolean _global_per_engine;
// 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
*** 262,272 ****
* @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 ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt);
if (scope != -1) {
return ScriptObjectMirror.unwrap(ctxt.getAttribute(name, scope), ctxtGlobal);
}
if (self == UNDEFINED) {
--- 262,272 ----
* @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) {
*** 315,325 ****
}
Context.checkPackageAccess(clazz);
}
ScriptObject realSelf = null;
! ScriptObject realGlobal = null;
if(thiz == null) {
// making interface out of global functions
realSelf = realGlobal = getNashornGlobalFrom(context);
} else if (thiz instanceof ScriptObjectMirror) {
final ScriptObjectMirror mirror = (ScriptObjectMirror)thiz;
--- 315,325 ----
}
Context.checkPackageAccess(clazz);
}
ScriptObject realSelf = null;
! Global realGlobal = null;
if(thiz == null) {
// making interface out of global functions
realSelf = realGlobal = getNashornGlobalFrom(context);
} else if (thiz instanceof ScriptObjectMirror) {
final ScriptObjectMirror mirror = (ScriptObjectMirror)thiz;
*** 344,354 ****
if (realSelf == null) {
throw new IllegalArgumentException(getMessage("interface.on.non.script.object"));
}
try {
! final ScriptObject oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != realGlobal);
try {
if (globalChanged) {
Context.setGlobal(realGlobal);
}
--- 344,354 ----
if (realSelf == null) {
throw new IllegalArgumentException(getMessage("interface.on.non.script.object"));
}
try {
! final Global oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != realGlobal);
try {
if (globalChanged) {
Context.setGlobal(realGlobal);
}
*** 369,430 ****
throw new RuntimeException(t);
}
}
// Retrieve nashorn Global object for a given ScriptContext object
! private ScriptObject getNashornGlobalFrom(final ScriptContext ctxt) {
if (_global_per_engine) {
// shared single global object for all ENGINE_SCOPE Bindings
return global;
}
final Bindings bindings = ctxt.getBindings(ScriptContext.ENGINE_SCOPE);
// is this Nashorn's own Bindings implementation?
if (bindings instanceof ScriptObjectMirror) {
! final ScriptObject sobj = globalFromMirror((ScriptObjectMirror)bindings);
! if (sobj != null) {
! return sobj;
}
}
// Arbitrary user Bindings implementation. Look for NASHORN_GLOBAL in it!
Object scope = bindings.get(NASHORN_GLOBAL);
if (scope instanceof ScriptObjectMirror) {
! final ScriptObject sobj = globalFromMirror((ScriptObjectMirror)scope);
! if (sobj != null) {
! return sobj;
}
}
// We didn't find associated nashorn global mirror in the Bindings given!
// Create new global instance mirror and associate with the Bindings.
final ScriptObjectMirror mirror = createGlobalMirror(ctxt);
bindings.put(NASHORN_GLOBAL, mirror);
! return mirror.getScriptObject();
}
// Retrieve nashorn Global object from a given ScriptObjectMirror
! private ScriptObject globalFromMirror(final ScriptObjectMirror mirror) {
ScriptObject sobj = mirror.getScriptObject();
! if (sobj instanceof GlobalObject && isOfContext(sobj, nashornContext)) {
! return sobj;
}
return null;
}
// Create a new ScriptObjectMirror wrapping a newly created Nashorn Global object
private ScriptObjectMirror createGlobalMirror(final ScriptContext ctxt) {
! final ScriptObject newGlobal = createNashornGlobal(ctxt);
return new ScriptObjectMirror(newGlobal, newGlobal);
}
// Create a new Nashorn Global object
! private ScriptObject createNashornGlobal(final ScriptContext ctxt) {
! final ScriptObject newGlobal = AccessController.doPrivileged(new PrivilegedAction<ScriptObject>() {
@Override
! public ScriptObject run() {
try {
return nashornContext.newGlobal();
} catch (final RuntimeException e) {
if (Context.DEBUG) {
e.printStackTrace();
--- 369,430 ----
throw new RuntimeException(t);
}
}
// Retrieve nashorn Global object for a given ScriptContext object
! private Global getNashornGlobalFrom(final ScriptContext ctxt) {
if (_global_per_engine) {
// shared single global object for all ENGINE_SCOPE Bindings
return global;
}
final Bindings bindings = ctxt.getBindings(ScriptContext.ENGINE_SCOPE);
// is this Nashorn's own Bindings implementation?
if (bindings instanceof ScriptObjectMirror) {
! final Global glob = globalFromMirror((ScriptObjectMirror)bindings);
! if (glob != null) {
! return glob;
}
}
// Arbitrary user Bindings implementation. Look for NASHORN_GLOBAL in it!
Object scope = bindings.get(NASHORN_GLOBAL);
if (scope instanceof ScriptObjectMirror) {
! final Global glob = globalFromMirror((ScriptObjectMirror)scope);
! if (glob != null) {
! return glob;
}
}
// We didn't find associated nashorn global mirror in the Bindings given!
// Create new global instance mirror and associate with the Bindings.
final ScriptObjectMirror mirror = createGlobalMirror(ctxt);
bindings.put(NASHORN_GLOBAL, mirror);
! return mirror.getHomeGlobal();
}
// Retrieve nashorn Global object from a given ScriptObjectMirror
! private Global globalFromMirror(final ScriptObjectMirror mirror) {
ScriptObject sobj = mirror.getScriptObject();
! if (sobj instanceof Global && isOfContext((Global)sobj, nashornContext)) {
! return (Global)sobj;
}
return null;
}
// Create a new ScriptObjectMirror wrapping a newly created Nashorn Global object
private ScriptObjectMirror createGlobalMirror(final ScriptContext ctxt) {
! final Global newGlobal = createNashornGlobal(ctxt);
return new ScriptObjectMirror(newGlobal, newGlobal);
}
// Create a new Nashorn Global object
! private Global createNashornGlobal(final ScriptContext ctxt) {
! final Global newGlobal = AccessController.doPrivileged(new PrivilegedAction<Global>() {
@Override
! public Global run() {
try {
return nashornContext.newGlobal();
} catch (final RuntimeException e) {
if (Context.DEBUG) {
e.printStackTrace();
*** 458,497 ****
}
return newGlobal;
}
// scripts should see "context" and "engine" as variables in the given global object
! private void setContextVariables(final ScriptObject 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 = ((GlobalObject)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
! ScriptObject invokeGlobal = null;
ScriptObjectMirror selfMirror = null;
if (selfObject instanceof ScriptObjectMirror) {
selfMirror = (ScriptObjectMirror)selfObject;
if (! isOfContext(selfMirror.getHomeGlobal(), nashornContext)) {
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 ScriptObject oldGlobal = Context.getGlobal();
invokeGlobal = oldGlobal;
if (oldGlobal == null) {
throw new IllegalArgumentException(getMessage("no.current.nashorn.global"));
}
--- 458,497 ----
}
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.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);
}
}
private Object invokeImpl(final Object selfObject, final String name, final Object... args) throws ScriptException, NoSuchMethodException {
name.getClass(); // null check
! Global invokeGlobal = null;
ScriptObjectMirror selfMirror = null;
if (selfObject instanceof ScriptObjectMirror) {
selfMirror = (ScriptObjectMirror)selfObject;
if (! isOfContext(selfMirror.getHomeGlobal(), nashornContext)) {
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"));
}
*** 500,510 ****
}
selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(selfObject, oldGlobal);
} else if (selfObject == null) {
// selfObject is null => global function call
! final ScriptObject ctxtGlobal = getNashornGlobalFrom(context);
invokeGlobal = ctxtGlobal;
selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(ctxtGlobal, ctxtGlobal);
}
if (selfMirror != null) {
--- 500,510 ----
}
selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(selfObject, oldGlobal);
} else if (selfObject == null) {
// selfObject is null => global function call
! final Global ctxtGlobal = getNashornGlobalFrom(context);
invokeGlobal = ctxtGlobal;
selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(ctxtGlobal, ctxtGlobal);
}
if (selfMirror != null) {
*** 530,544 ****
private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt) throws ScriptException {
return evalImpl(script, ctxt, getNashornGlobalFrom(ctxt));
}
! private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final ScriptObject ctxtGlobal) throws ScriptException {
if (script == null) {
return null;
}
! final ScriptObject oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != ctxtGlobal);
try {
if (globalChanged) {
Context.setGlobal(ctxtGlobal);
}
--- 530,544 ----
private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt) throws ScriptException {
return evalImpl(script, ctxt, getNashornGlobalFrom(ctxt));
}
! private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException {
if (script == null) {
return null;
}
! final Global oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != ctxtGlobal);
try {
if (globalChanged) {
Context.setGlobal(ctxtGlobal);
}
*** 556,566 ****
Context.setGlobal(oldGlobal);
}
}
}
! private static void throwAsScriptException(final Exception e, final ScriptObject global) throws ScriptException {
if (e instanceof ScriptException) {
throw (ScriptException)e;
} else if (e instanceof NashornException) {
final NashornException ne = (NashornException)e;
final ScriptException se = new ScriptException(
--- 556,566 ----
Context.setGlobal(oldGlobal);
}
}
}
! private static void throwAsScriptException(final Exception e, final Global global) throws ScriptException {
if (e instanceof ScriptException) {
throw (ScriptException)e;
} else if (e instanceof NashornException) {
final NashornException ne = (NashornException)e;
final ScriptException se = new ScriptException(
*** 580,590 ****
private CompiledScript asCompiledScript(final Source source) throws ScriptException {
final ScriptFunction func = compileImpl(source, context);
return new CompiledScript() {
@Override
public Object eval(final ScriptContext ctxt) throws ScriptException {
! final ScriptObject globalObject = getNashornGlobalFrom(ctxt);
// Are we running the script in the correct global?
if (func.getScope() == globalObject) {
return evalImpl(func, ctxt, globalObject);
}
// ScriptContext with a different global. Compile again!
--- 580,590 ----
private CompiledScript asCompiledScript(final Source source) throws ScriptException {
final ScriptFunction func = compileImpl(source, context);
return new CompiledScript() {
@Override
public Object eval(final ScriptContext ctxt) throws ScriptException {
! final Global globalObject = getNashornGlobalFrom(ctxt);
// Are we running the script in the correct global?
if (func.getScope() == globalObject) {
return evalImpl(func, ctxt, globalObject);
}
// ScriptContext with a different global. Compile again!
*** 600,611 ****
private ScriptFunction compileImpl(final Source source, final ScriptContext ctxt) throws ScriptException {
return compileImpl(source, getNashornGlobalFrom(ctxt));
}
! private ScriptFunction compileImpl(final Source source, final ScriptObject newGlobal) throws ScriptException {
! final ScriptObject oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != newGlobal);
try {
if (globalChanged) {
Context.setGlobal(newGlobal);
}
--- 600,611 ----
private ScriptFunction compileImpl(final Source source, final ScriptContext ctxt) throws ScriptException {
return compileImpl(source, getNashornGlobalFrom(ctxt));
}
! private ScriptFunction compileImpl(final Source source, final Global newGlobal) throws ScriptException {
! final Global oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != newGlobal);
try {
if (globalChanged) {
Context.setGlobal(newGlobal);
}
*** 639,648 ****
}
}
return true;
}
! private static boolean isOfContext(final ScriptObject global, final Context context) {
! assert global instanceof GlobalObject: "Not a Global object";
! return ((GlobalObject)global).isOfContext(context);
}
}
--- 639,647 ----
}
}
return true;
}
! private static boolean isOfContext(final Global global, final Context context) {
! return global.isOfContext(context);
}
}