ScriptObjectMirrors
Serguei Mourachov
smourachov at gmail.com
Fri Oct 17 03:53:04 UTC 2014
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
More information about the nashorn-dev
mailing list