aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsundar <none@none>2016-12-01 18:53:51 +0530
committersundar <none@none>2016-12-01 18:53:51 +0530
commit3f33964dad201d787c35cab878f6cc6fba9d3253 (patch)
treef84258e4233d1bacd0b0dff40dace23aa4b73f46
parentffa2072fb8161a21b86684fa8f701f309d8d434f (diff)
downloadjdk8u_nashorn-3f33964dad201d787c35cab878f6cc6fba9d3253.tar.gz
8170565: JSObject call() is passed undefined for the argument 'thiz'
Reviewed-by: hannesw, jlaskey, attila
-rw-r--r--src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java22
-rw-r--r--test/src/jdk/nashorn/api/scripting/test/ScriptObjectMirrorTest.java38
2 files changed, 58 insertions, 2 deletions
diff --git a/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java b/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java
index e8e493b3..7eb23a9b 100644
--- a/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java
+++ b/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java
@@ -39,9 +39,13 @@ import jdk.internal.dynalink.linker.LinkerServices;
import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
import jdk.nashorn.api.scripting.JSObject;
+import jdk.nashorn.api.scripting.ScriptObjectMirror;
import jdk.nashorn.internal.lookup.MethodHandleFactory;
import jdk.nashorn.internal.lookup.MethodHandleFunctionality;
+import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.objects.Global;
/**
* A Dynalink linker to handle web browser built-in JS (DOM etc.) objects as well
@@ -141,9 +145,9 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker {
}
private static GuardedInvocation findCallMethod(final CallSiteDescriptor desc) {
- MethodHandle mh = JSOBJECT_CALL;
+ MethodHandle mh = NashornCallSiteDescriptor.isScope(desc)? JSOBJECT_SCOPE_CALL : JSOBJECT_CALL;
if (NashornCallSiteDescriptor.isApplyToCall(desc)) {
- mh = MH.insertArguments(JSOBJECT_CALL_TO_APPLY, 0, JSOBJECT_CALL);
+ mh = MH.insertArguments(JSOBJECT_CALL_TO_APPLY, 0, mh);
}
final MethodType type = desc.getMethodType();
mh = type.parameterType(type.parameterCount() - 1) == Object[].class ?
@@ -214,6 +218,19 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker {
}
}
+ // This is used when a JSObject is called as scope call to do undefined -> Global this translation.
+ @SuppressWarnings("unused")
+ private static Object jsObjectScopeCall(final JSObject jsObj, final Object thiz, final Object[] args) {
+ final Object modifiedThiz;
+ if (thiz == ScriptRuntime.UNDEFINED && !jsObj.isStrictFunction()) {
+ final Global global = Context.getGlobal();
+ modifiedThiz = ScriptObjectMirror.wrap(global, global);
+ } else {
+ modifiedThiz = thiz;
+ }
+ return jsObj.call(modifiedThiz, args);
+ }
+
private static final MethodHandleFunctionality MH = MethodHandleFactory.getFunctionality();
// method handles of the current class
@@ -225,6 +242,7 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker {
private static final MethodHandle JSOBJECT_GETMEMBER = findJSObjectMH_V("getMember", Object.class, String.class);
private static final MethodHandle JSOBJECT_SETMEMBER = findJSObjectMH_V("setMember", Void.TYPE, String.class, Object.class);
private static final MethodHandle JSOBJECT_CALL = findJSObjectMH_V("call", Object.class, Object.class, Object[].class);
+ private static final MethodHandle JSOBJECT_SCOPE_CALL = findOwnMH_S("jsObjectScopeCall", Object.class, JSObject.class, Object.class, Object[].class);
private static final MethodHandle JSOBJECT_CALL_TO_APPLY = findOwnMH_S("callToApply", Object.class, MethodHandle.class, JSObject.class, Object.class, Object[].class);
private static final MethodHandle JSOBJECT_NEW = findJSObjectMH_V("newObject", Object.class, Object[].class);
diff --git a/test/src/jdk/nashorn/api/scripting/test/ScriptObjectMirrorTest.java b/test/src/jdk/nashorn/api/scripting/test/ScriptObjectMirrorTest.java
index f9c78fc7..7656dc6b 100644
--- a/test/src/jdk/nashorn/api/scripting/test/ScriptObjectMirrorTest.java
+++ b/test/src/jdk/nashorn/api/scripting/test/ScriptObjectMirrorTest.java
@@ -41,6 +41,7 @@ import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
+import jdk.nashorn.api.scripting.AbstractJSObject;
import jdk.nashorn.api.scripting.JSObject;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
import org.testng.annotations.Test;
@@ -386,4 +387,41 @@ public class ScriptObjectMirrorTest {
assertTrue(func.isFunction());
assertEquals(func.call(e.eval("this"), "hello"), "hello world");
}
+
+ // @bug 8170565: JSObject call() is passed undefined for the argument 'thiz'
+ @Test
+ public void jsObjectThisTest() throws Exception {
+ final ScriptEngineManager engineManager = new ScriptEngineManager();
+ final ScriptEngine e = engineManager.getEngineByName("nashorn");
+ e.put("func", new AbstractJSObject() {
+ @Override
+ public boolean isFunction() { return true; }
+
+ @Override
+ public Object call(Object thiz, Object...args) {
+ return thiz;
+ }
+ });
+
+ assertTrue((boolean)e.eval("func() === this"));
+
+ // check that there is no blind undefined->Global translation!
+ assertTrue((boolean)e.eval("typeof(Function.prototype.call.call(func, undefined)) == 'undefined'"));
+
+ // make sure that strict functions don't get translated this for scope calls!
+ e.put("sfunc", new AbstractJSObject() {
+ @Override
+ public boolean isFunction() { return true; }
+
+ @Override
+ public boolean isStrictFunction() { return true; }
+
+ @Override
+ public Object call(Object thiz, Object...args) {
+ return thiz;
+ }
+ });
+
+ assertTrue((boolean)e.eval("typeof sfunc() == 'undefined'"));
+ }
}