Sundar
Will it also affect classes implementing JSObject?
IMO, we should have an option to disable this wrap/unwrap behavior in
cases when it significantly affecting performance.
SM
On 10/16/2014 6:44 AM, A. Sundararajan wrote:
There were many questions in this list and elsewhere on
ScriptObjectMirror. This email is to clarify those.
Nashorn represents JavaScript objects as instances of implementation
class called jdk.nashorn.internal.runtime.ScriptObject or one of it's
subclasses (like NativeArray, NativeRegExp etc. - or even generated
ones like jdk.nashorn.internal.scripts.JO4 etc)
When ScriptObjects are returned from a script function or evaluated
script code, ScriptEngine.eval returns an instanceof
jdk.nashorn.api.scripting.ScriptObjectMirror.
http://cr.openjdk.java.net/~sundar/jdk.nashorn.api/9/javadoc/jdk/nashorn/api/scripting/ScriptObjectMirror.html
Example:
ScriptEngine e = new
ScriptEngineManager().getEngineByName("nashorn");
Object obj = e.eval("var obj = { foo: 23 }"); // obj is an
instance of ScriptObjectMirror
Caller can cast the result to ScriptObjectMirror to access properties
of that script object or call methods on it. All javax.script
interface methods returning Object (ScriptEngine.eval,
Invocable.invokeFunction, Invocable.invokeMethod) return
ScriptObjectMirror if underlying script or script function/method
returns a JS object.
But, if you call any Java method accepting Object type param or assign
to element of Object[], then Nashorn was not wrapping ScriptObject in
the past. i.e., 'raw' ScriptObject (or subclass) instances "escaped"
to Java layer. If you try to cast those to ScriptObjectMirror from
Java code, you got ClassCastException. Also, if you passed such raw
object as "self" parameter for Invocable.invokeMethod, you would
IllegalArgumentException. This was causing a lot of confusion - script
objects got to java code sometimes as wrapped mirror objects and
sometimes as 'raw' objects!
With a recent change
http://hg.openjdk.java.net/jdk9/dev/nashorn/rev/a8d44c7c2ac0
in jdk9 and the corresponding backport to jdk8u-dev
http://hg.openjdk.java.net/jdk8u/jdk8u-dev/nashorn/rev/a35c8136c045
the way nashorn wraps internal ScriptObjects to ScriptObjectMirror has
changed. Script objects are always wrapped to ScriptObjectMirror -
even when you're calling Java method that accepts "Object" type value.
Also, return values from java methods returning Object are "unwrapped"
(if the return value is a ScriptObjectMirror) when it gets to script
execution.
Example:
// list gets ScriptObjectMirror as element
engine.eval("var m = new java.util.HashMap(); l.put('myobj', {
foo: 33 });");
engine.eval("var obj = m.get('myobj'); // obj gets unwrapped as
ScriptObject here");
With this change, raw ScriptObjects don't escape to Java layer at all.
Hope this helps,
-Sundar