Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JavaScript objects passed into function not "copy of reference" when using execute from Java #3247

Closed
jessica-d-pennell-at-xcelenergy opened this issue Feb 26, 2021 · 5 comments
Assignees
Labels

Comments

@jessica-d-pennell-at-xcelenergy
Copy link

Describe GraalVM and your environment :

  • GraalVM version : org.graalvm.js:js:21.0.0.2, org.graalvm.js:js-scriptengine:21.0.0.2
  • JDK version: OpenJDK 11
  • OS and OS Version: Windows 10
  • Architecture: Intel(R) Core(TM) i7-8665U CUP @ 1.90GHz 2.11 GHz
  • The output of java -Xinternalversion:
OpenJDK 64-Bit Server VM (11.0.2+9) for windows-amd64 JRE (11.0.2+9), built on Jan 18 2019 05:23:22 by "mach5one" with MS VC++ 15.5 (VS2017)

Describe the issue
Normally JavaScript objects passed into functions are "copy of reference". That is to say that given this input

function changeStuff(a, b, c)
{
  a = a * 10;
  b.item = "changed";
  c = {item: "changed"};
}

var num = 10;
var obj1 = {item: "unchanged"};
var obj2 = {item: "unchanged"};

changeStuff(num, obj1, obj2);

console.log(num);
console.log(obj1.item);
console.log(obj2.item);

We would expect this output

10
changed
unchanged

Notice the 2nd object changed.

I have not yet found a way to get this to happen on my end. It is possible there is a pointer/reference method that I am not yet aware of, but everything I have tried (and I have tried a lot) will not allow me to update obj1.item inside of a function body when I call execute. I am using a single context.

Code snippet or code repository that reproduces the issue

context.getBindings("js").getMember("exports")

The above contains a Value whose guest object is an empty JSOrdinaryObject

Function source

function(__, require, resolve, log, exports, module) { exports.get = function () {}; }

Executing function source

myFuncValue.execute(argv)

When this happens, exports is unchanged, no get function attached.

Be gentle, this is a work in progress, I am going to include the source where this occurred in this ticket.

Steps to reproduce the issue

  1. Clone https://gitlab.com/jessica.d.pennell/purplejs-with-graalvm.git
  2. Build the project with Gradle 5.1.1
  3. Set a watch on line 1296 of modules/purplejs-core/src/main/java/io/purplejs/core/graalvm/GraalVMSOM.java

Expected behavior

  1. result is null/undefined.
  2. export has one member, a function called get.

Observed Behavior

  1. result is null/undefined (good)
  2. export has no members (bad)

Note : To see an example of member functions being pulled successfully, observe when the JSON built-in is boxed and its members parse and stringify are extracted successfully

Additional context
Code examples CC-BY-SA from here https://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language

@jessica-d-pennell-at-xcelenergy
Copy link
Author

Almost forgot the arguments to the function.
image
The 5th object (index 4) is a custom ScriptObjectMirror object with these contents
image

myReflection is an ordinary polyglot Value (https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/Value.html#as-java.lang.Class-) object

@jessica-d-pennell-at-xcelenergy
Copy link
Author

For the time being, to work around this, I will be using function.protototype.apply similar to the following

result = getContext().eval("js", "var argv = [\"hi\"]; var thiz = {}; function test(arg1) { console.log(arg1); this.test2 = \"why hello!\"; }; test.apply(thiz, argv); thiz.test2");

This works for modifying members of passed in arguments,

getContext().eval("js", "var argv = [{}]; var thiz = {}; function test(arg1) { arg1.test1 = \"hi there\"; this.test2 = \"why hello!\"; }; test.apply(thiz, argv); argv[0].test1")

Outputs "hi there"

So I don't really need Value.execute, it is just a "nice to have". But I would like to know if this is a real bug or if there is some magic I need to perform to get Value.execute to work normally.

@oubidar-Abderrahim
Copy link
Member

Thank you for reporting this, I can take this to the Truffle team, but it would be much appreciated if we can have a smaller reproducer, would you mind providing a small java class with the changeStuff example you've shown with and without the workaround. This would reduce debugging time considerably.

Also, I'm wondering why you're using an old version of java11?

@oubidar-Abderrahim oubidar-Abderrahim self-assigned this Mar 1, 2021
@oubidar-Abderrahim
Copy link
Member

Were you able to get a small reproducer for this issue? FYI I couldn't access the GitLab repo you provided.

@oubidar-Abderrahim
Copy link
Member

Closing for inactivity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants