Skip to content

Fix Java object conversion in ScriptEngine bindings - #2490

Merged
gbrail merged 4 commits into
mozilla:masterfrom
Hanabi9248:codex/jsr223-binding-conversion
Sep 27, 2026
Merged

gbrail merged 4 commits into
mozilla:masterfrom
Hanabi9248:codex/jsr223-binding-conversion

Conversation

@Hanabi9248

@Hanabi9248 Hanabi9248 commented Sep 12, 2026 •

Copy link
Copy Markdown
Contributor

After engine.put("file", file) and engine.eval("var copy = file"), engine.get("copy") returns a NativeJavaObject rather than the original Java object. BindingsObject converts values in the wrong direction when reading them.

Convert Java values to JavaScript on reads. On writes, unwrap only Wrapper values so Java objects retain their identity while native JavaScript values, including undefined, remain unchanged. Converting every write with jsToJava(Object.class) would turn undefined into a string.

Regression tests cover Java object identity, global bindings, and native JavaScript values through direct/compiled evaluation in both execution modes. All 43 engine tests pass locally; the four new native-value cases fail on the preceding PR revision. Formatting and test compilation pass. Full Linux CI passes on revised head 39d05f2: Java 21, Java 25, debug, multithreaded, and Test262 jobs.

The reversed conversions were also noted in #798; its separate const-scope issue remains outside this change. Please squash the commits when merging.

@gbrail

gbrail commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

Agreed -- I guess this can't be used all that much...

The first one is clear -- get should do the conversion in the other direction.

However, put is triggered when the JavaScript code sets a global that came from the context. But by calling jsToJava with Object.class as the target type, we end up with a converted Java object, which we might not always want. For example, imagine if we wanted to return the original JavaScript object, such as Undefined? This code would actually convert it to something else. I find the Java specs to be unhelpful on this, but do we want a conversion, or perhaps we want a different conversion?

@Hanabi9248

Copy link
Copy Markdown
Contributor Author

You’re right: jsToJava(value, Object.class) is too broad here. With var missing = undefined, the preceding revision stores the string "undefined", so reading the binding back changes its JavaScript semantics.

I changed put to unwrap only Wrapper values and leave everything else unchanged. This keeps the original Java object for var copy = file without coercing native JavaScript values. Four added cases cover direct/compiled evaluation in both execution modes, checking Undefined identity and subsequent use of a date, object, array and function. All four fail on the preceding revision; all 43 engine tests pass with this change.

The updated head is 39d05f2. The full Linux workflow is running; its result is still pending.

@gbrail

gbrail commented Sep 27, 2026

Copy link
Copy Markdown
Collaborator

This looks good now and it's a great catch. Thanks!

@gbrail
gbrail merged commit 54aa0a5 into mozilla:master Sep 27, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants