Skip to content

ScriptEngine behaviour is non-standard and different to Nashorn #47

@nhoughto

Description

@nhoughto

As per the Java Scripting API docs (https://docs.oracle.com/javase/7/docs/api/javax/script/ScriptContext.html) a ScriptEngine should honour the Scope of a Binding:

ENGINE_SCOPE: EngineScope attributes are visible during the lifetime of a single ScriptEngine and a set of attributes is maintained for each engine.
GLOBAL_SCOPE: GlobalScope attributes are visible to all engines created by same ScriptEngineFactory.

So I expect that an attribute set with a Global scope should be accessible to all engines from the same ScriptEngine, this does not appear to be the behaviour in graaljs though.

GraalJS code that fails:

        ScriptEngine eng = new ScriptEngineManager().getEngineByName("graal.js");
        eng.getBindings(ScriptContext.GLOBAL_SCOPE).put("globalThing", "asdf");
        Object globalResult = eng.eval("globalThing", eng.getBindings(ScriptContext.GLOBAL_SCOPE));
        Object engineResult = eng.eval("globalThing", eng.getBindings(ScriptContext.ENGINE_SCOPE));

with:

Exception in thread "main" javax.script.ScriptException: org.graalvm.polyglot.PolyglotException: ReferenceError: globalThing is not defined
	at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:199)
	at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:176)
	at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:233)
	at Main.main(Main.java:15)
Caused by: org.graalvm.polyglot.PolyglotException: ReferenceError: globalThing is not defined
	at <js>.:program(<eval>:1)
	at org.graalvm.polyglot.Context.eval(Context.java:313)
	at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:197)
	... 3 more

Same code with nashorn engine that works:

        ScriptEngine eng = new ScriptEngineManager().getEngineByName("nashorn");
        eng.getBindings(ScriptContext.GLOBAL_SCOPE).put("globalThing", "asdf");
        Object globalResult = eng.eval("globalThing", eng.getBindings(ScriptContext.GLOBAL_SCOPE));
        Object engineResult = eng.eval("globalThing", eng.getBindings(ScriptContext.ENGINE_SCOPE));

I'm looking into JSR223 APIs as i'm trying to find a clean way of either sharing values across Graal Contexts or "resetting" a context after an execution and Bindings / Scopes seem a good way to do it, relates to oracle/graal#631

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions