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