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

Fix uncurryThis on Nashorn #1129

Merged
merged 2 commits into from
Sep 27, 2022
Merged

Fix uncurryThis on Nashorn #1129

merged 2 commits into from
Sep 27, 2022

Conversation

AprilArcus
Copy link
Contributor

Under Nashorn, certain class methods such as String#startsWith(), which would normally be defined as members of String.prototype,

> ''.startsWith === String.prototype.startsWith
< true

are instead defined in Java bytecode:

> java_import 'javax.script.ScriptEngineManager'
> engine = ScriptEngineManager.new.get_engine_by_name('nashorn')
> engine.eval("''.startsWith === String.prototype.startsWith")
< false
> engine.eval("''.endsWith")
< #<Java::JdkDynalinkBeans::SimpleDynamicMethod:0x123ca460>

This means that they cannot be invoked with .call, .bind, and .apply in a normal way:

> engine.eval("'foo'.startsWith('f')")
< true
> engine.eval("'foo'.startsWith.call('foo', 'f')")
       16: from javax.script.AbstractScriptEngine.eval(javax/script/AbstractScriptEngine.java:264)
       15: from jdk.nashorn.api.scripting.NashornScriptEngine.eval(jdk/nashorn/api/scripting/NashornScriptEngine.java:162)
       14: from jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(jdk/nashorn/api/scripting/NashornScriptEngine.java:409)
       13: from jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(jdk/nashorn/api/scripting/NashornScriptEngine.java:413)
       12: from jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(jdk/nashorn/api/scripting/NashornScriptEngine.java:456)
       11: from jdk.nashorn.internal.runtime.ScriptRuntime.apply(jdk/nashorn/internal/runtime/ScriptRuntime.java:527)
       10: from jdk.nashorn.internal.runtime.ScriptFunction.invoke(jdk/nashorn/internal/runtime/ScriptFunction.java:513)
        9: from jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(jdk/nashorn/internal/runtime/ScriptFunctionData.java:655)
        8: from jdk.nashorn.internal.scripts.Script$Recompilation$3$\^eval\_/0x0000000800765040.:program(jdk/nashorn/internal/scripts/<eval>:1)
        7: from jdk.dynalink.DynamicLinker.relink(jdk/dynalink/DynamicLinker.java:242)
        6: from jdk.dynalink.LinkerServicesImpl.getGuardedInvocation(jdk/dynalink/LinkerServicesImpl.java:135)
        5: from jdk.dynalink.LinkerServicesImpl.getWithLookupInternal(jdk/dynalink/LinkerServicesImpl.java:168)
        4: from jdk.dynalink.LinkerServicesImpl.lambda$getGuardedInvocation$0(jdk/dynalink/LinkerServicesImpl.java:137)
        3: from jdk.dynalink.linker.support.CompositeGuardingDynamicLinker.getGuardedInvocation(jdk/dynalink/linker/support/CompositeGuardingDynamicLinker.java:109)
        2: from jdk.nashorn.internal.runtime.linker.NashornBottomLinker.getGuardedInvocation(jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java:78)
        1: from jdk.nashorn.internal.runtime.linker.NashornBottomLinker.linkBean(jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java:126)
Java::JavaLang::AssertionError (unknown call type GET:METHOD|PROPERTY|ELEMENT:call(Object)Object@jdk.nashorn.internal.scripts.Script$Recompilation$3$\^eval\_/0x0000000800765040)

causing an errors to be thrown from Nashorn when a polyfill which attempts to compose the native implementations is initialized.

This PR introduces a small change to uncurryThis, which disqualifies functions from the native bind code path if they do not descend from the JavaScript Function constructor. It replaces and subsets a falsey check.

Under Nashorn, certain class methods such as `String#startsWith()`,
which would normally be defined as members of String.prototype,

```
> ''.startsWith === String.prototype.startsWith
< true
```

are instead defined in Java bytecode:

```
> java_import 'javax.script.ScriptEngineManager'
> engine = ScriptEngineManager.new.get_engine_by_name('nashorn')
> engine.eval("''.startsWith === String.prototype.startsWith")
< false
> engine.eval("''.endsWith")
< #<Java::JdkDynalinkBeans::SimpleDynamicMethod:0x123ca460>
```

This means that they cannot be invoked with .call, .bind, and .apply in
a normal way:

```
> engine.eval("'foo'.startsWith('f')")
< true
> engine.eval("'foo'.startsWith.call('foo', 'f')")
       16: from javax.script.AbstractScriptEngine.eval(javax/script/AbstractScriptEngine.java:264)
       15: from jdk.nashorn.api.scripting.NashornScriptEngine.eval(jdk/nashorn/api/scripting/NashornScriptEngine.java:162)
       14: from jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(jdk/nashorn/api/scripting/NashornScriptEngine.java:409)
       13: from jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(jdk/nashorn/api/scripting/NashornScriptEngine.java:413)
       12: from jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(jdk/nashorn/api/scripting/NashornScriptEngine.java:456)
       11: from jdk.nashorn.internal.runtime.ScriptRuntime.apply(jdk/nashorn/internal/runtime/ScriptRuntime.java:527)
       10: from jdk.nashorn.internal.runtime.ScriptFunction.invoke(jdk/nashorn/internal/runtime/ScriptFunction.java:513)
        9: from jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(jdk/nashorn/internal/runtime/ScriptFunctionData.java:655)
        8: from jdk.nashorn.internal.scripts.Script$Recompilation$3$\^eval\_/0x0000000800765040.:program(jdk/nashorn/internal/scripts/<eval>:1)
        7: from jdk.dynalink.DynamicLinker.relink(jdk/dynalink/DynamicLinker.java:242)
        6: from jdk.dynalink.LinkerServicesImpl.getGuardedInvocation(jdk/dynalink/LinkerServicesImpl.java:135)
        5: from jdk.dynalink.LinkerServicesImpl.getWithLookupInternal(jdk/dynalink/LinkerServicesImpl.java:168)
        4: from jdk.dynalink.LinkerServicesImpl.lambda$getGuardedInvocation$0(jdk/dynalink/LinkerServicesImpl.java:137)
        3: from jdk.dynalink.linker.support.CompositeGuardingDynamicLinker.getGuardedInvocation(jdk/dynalink/linker/support/CompositeGuardingDynamicLinker.java:109)
        2: from jdk.nashorn.internal.runtime.linker.NashornBottomLinker.getGuardedInvocation(jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java:78)
        1: from jdk.nashorn.internal.runtime.linker.NashornBottomLinker.linkBean(jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java:126)
Java::JavaLang::AssertionError (unknown call type GET:METHOD|PROPERTY|ELEMENT:call(Object)Object@jdk.nashorn.internal.scripts.Script$Recompilation$3$\^eval\_/0x0000000800765040)
```

causing an errors to be thrown from Nashorn when a polyfill which
attempts to compose the native implementations is initialized.

This PR introduces a small change to `uncurryThis`, which disqualifies
functions from the native bind code path if they do not descend from
the JavaScript `Function` constructor. It replaces and subsets a falsey
check.
@AprilArcus
Copy link
Contributor Author

AprilArcus commented Sep 27, 2022

I think this approach is slightly better than 27b5630, as it checks each function and allows the majority of normal functions to go down the preferred path.

@zloirock
Copy link
Owner

Let it be, thanks.

@zloirock zloirock merged commit 9307fb7 into zloirock:master Sep 27, 2022
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