ScriptObjectMirrors
Serguei Mourachov
smourachov at gmail.com
Fri Oct 17 04:12:09 UTC 2014
I mean methods of JSObject such as (get/set)(Member/Slot) and call(). I
hope object passed to/from those will not be wrapped/unwrapped, although
the are technically Java methods .
SM
On 10/16/2014 9:01 PM, A. Sundararajan wrote:
> There is no notion of wrap/unwrap of user implemented JSObject - so
> those won't be affected. JSObject itself is just another Java type and
> so would be between script and Java code "as is".
>
> Only for Object param types of Java methods will receive wrapped
> ScriptObjects - argument filter will be inserted for such parameters.
> Actually a filter is already installed for such params to handle
> ConsString objects - so ScriptObject wrapping is just another
> incremental check+wrap in that filter. And Object returning Java
> methods will have unwrapper filter on return value (on the script
> side). Other Java parameter types/return type should not be affected
> at all. Providing another command line option implies we keep checking
> it in argument/return type filter methods - which would be costly.
>
> -Sundar
>
> On Friday 17 October 2014 09:23 AM, Serguei Mourachov wrote:
>> 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