I *don't think* there should be any (un)wrapping applied to JSObject
method calls. The api doc says: "Nashorn will treat objects of such
classes just like nashorn script objects."
And, personally, I'm fine with that. That will allow me to provide more
efficient implementation of java objects injected inside the script
environment.
I understand the motivation to use (un)wrapping everywhere when
crossing Java/JS boundary, but in my particular use-case, where JS is
doing a lot of object manipulation and computation, using java objects
provided by my code(mainly Maps ans Lists), all the (un)wrapping could
be very expensive.
SM
On 10/16/2014 9:35 PM, A. Sundararajan wrote:
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