ScriptObjectMirrors
A. Sundararajan
sundararajan.athijegannathan at oracle.com
Fri Oct 17 04:35:08 UTC 2014
I need to check that out. But, is there any specific reason why it
should be different? User implemented JSObject receives Object (for set,
call) and returns Object. If script object is passed as argument to
those, do you think that should be wrapped as mirror? if so, why?
-Sundar
On Friday 17 October 2014 09:42 AM, Serguei Mourachov wrote:
> 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