Using === across different contexts
Sundararajan Athijegannathan
sundararajan.athijegannathan at oracle.com
Tue Dec 22 04:10:27 UTC 2015
Actually, I'm not sure if depending on === in the code is a good
approach -- particularly, for objects that are not script objects of
the current world. These are to be treated like "host objects" in
ECMAScript-speak. i.e., regular rules of script objects don't always
apply to 'host objects'. The === operator for Java objects is
interpreted as object identity -- and the same rule for
ScriptObjectMirrors -- in that both are "host objects" from the
standpoint of the 'current world'.
-Sundar
On 12/22/2015 9:34 AM, Vivin Suresh Paliath wrote:
> Thanks for the response! I understand that in general it would be
> difficult for foreign objects. But this seems like surprising behavior
> given that these are both JavaScript objects. That they are unequal
> seems to be an artifact of the implementation (the fact that JS
> objects from different contexts are treated as foreign). Could JS
> objects be treated differently?
>
> After going through the Nashorn source, I decided to try this very
> naive approach adding the following test to
> ScriptRuntime#equalSameTypeValues:
>
> if(x instanceof ScriptObjectMirror && y instanceof ScriptObjectMirror) {
> return x.equals(y);
> }
>
> After this change, the code now returns true, because
> ScriptObjectMirror#equals compares the actual objects. I am not sure
> if this breaks anything though (been trying to run the test suite, but
> end up getting some errors from make). Is there a reason this
> particular fix is a bad idea? I can't think of a particular reason
> why. From the perspective of the runtime, I can't see a reason why
> those two objects should be considered different.
>
> I will investigate the eval approach, but ideally I would like
> something that doesn't impose any changes on the JS code. I am
> developing a simple runtime that exposes some objects and utilities,
> and where custom scripts can run in their own contexts. The fact that
> === returns false in these cases leads to some very strange behavior.
>
> On Mon, Dec 21, 2015 at 8:48 PM, Sundararajan Athijegannathan
> <sundararajan.athijegannathan at oracle.com
> <mailto:sundararajan.athijegannathan at oracle.com>> wrote:
>
> Unless we create mirrors as weak refs internally (i.e., maintain
> 1:1 with underlying foreign object reference), there is no easy
> solution. And maintaining such weak refs is unnecessarily complex.
> "Foreign object" call/access is mean to be just a "lightweight
> wrapper" based access. That said, you can do the === on the
> foreign context itself. You can call ScriptObjectMirror's eval to
> evaluate === test in that foreign context. That would get right
> object identity.
>
> -Sundar
>
>
> On 12/22/2015 4:26 AM, Vivin Suresh Paliath wrote:
>
> One more thing I noticed is that apparently a new
> ScriptObjectMirror
> instance is probably being created each time x is
> dereferenced, so "e.x ===
> e.x" also returns "false".
>
> On Mon, Dec 21, 2015 at 3:49 PM, Vivin Suresh Paliath <
> vivin.paliath at gmail.com <mailto:vivin.paliath at gmail.com>> wrote:
>
> I ran into an issue where === returns false even when both
> should be
> pointing to the same object. I'm assuming this is because
> one of the
> objects is wrapped by a ScriptObjectMirror, because it was
> defined in a
> different context.
>
> Here's some code that demonstrates this:
>
> ScriptEngine engine = new
> NashornScriptEngineFactory().getScriptEngine(
> new String[] { "-strict" }
> );
>
> try {
> engine.eval("function Foo(src) { this.src =
> src }; var e = {
> x: new Foo(\"what\") };");
>
> ScriptContext c = new SimpleScriptContext();
> c.setBindings(engine.createBindings(),
> ScriptContext.ENGINE_SCOPE);
>
> c.getBindings(ScriptContext.ENGINE_SCOPE).putAll(engine.getBindings(ScriptContext.ENGINE_SCOPE));
>
> System.out.println(engine.eval("var z = e.x;
> z === e.x;", c));
> } catch(Exception e) {
> throw new RuntimeException(e);
> }
>
> This prints out "false". Is there a way around this? I am
> also explicitly
> copying over all the bindings from the parent scope into
> the new scope so
> that I have access to "e". Could this be the source of the
> problem, and if
> so, is there a better way to achieve what I'm trying to do?
>
> --
> Ruin untold;
> And thine own sadness,
> Sing in the grass,
> When eve has forgot, that no more hear common things that
> gleam and pass;
> But seek alone to lip, sad Rose of love and ruin untold;
> And thine own mother
> Can know it as I know
> More than another
> What makes your own sadness,
> Set in her eyes.
>
> map{@n=split//;$j.=$n[0]x$n[1]}split/:/,"01:11:02".
> ":11:01:11:02:13:01:11:01:11:01:13:02:12:01:13:01".
> ":11:04:11:06:12:04:11:01:12:01:13:02:12:01:14:01".
> ":13:01:11:03:12:01:11:04:12:02:11:01:11:01:13:02".
> ":11:03:11:06:11:01:11:05:12:02:11:01:11:01:13:02".
> ":11:02:12:01:12:04:11:06:12:01:11:04:12:04:11:01".
> ":12:03:12:01:12:01:11:01:12:01:12:02:11:01:11:01".
> ":13:02:11:01:02:11:01:12:02";map{print chr unpack"
> i",pack"B32",$_}$j=~m/.{8}/g
>
>
>
>
>
>
>
> --
> Ruin untold;
> And thine own sadness,
> Sing in the grass,
> When eve has forgot, that no more hear common things that gleam and pass;
> But seek alone to lip, sad Rose of love and ruin untold;
> And thine own mother
> Can know it as I know
> More than another
> What makes your own sadness,
> Set in her eyes.|
>
> map{@n=split//;$j.=$n[0]x$n[1]}split/:/,"01:11:02".
> ":11:01:11:02:13:01:11:01:11:01:13:02:12:01:13:01".
> ":11:04:11:06:12:04:11:01:12:01:13:02:12:01:14:01".
> ":13:01:11:03:12:01:11:04:12:02:11:01:11:01:13:02".
> ":11:03:11:06:11:01:11:05:12:02:11:01:11:01:13:02".
> ":11:02:12:01:12:04:11:06:12:01:11:04:12:04:11:01".
> ":12:03:12:01:12:01:11:01:12:01:12:02:11:01:11:01".
> ":13:02:11:01:02:11:01:12:02";map{print chr unpack"
> i",pack"B32",$_}$j=~m/.{8}/g
> |
More information about the nashorn-dev
mailing list