aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorasaha <none@none>2015-01-28 15:33:44 -0800
committerasaha <none@none>2015-01-28 15:33:44 -0800
commit8c0022c081d3b2d4c9ea0d7be19f7ff630a10d0d (patch)
tree22de2f75e706178b2e8af265d7d075fb6b8ceb55
parentfdf35cb12235b2a116b2826d00a6bb76e726a25b (diff)
parentfe3280922525ab94f98ed8687bb728b60dec55c8 (diff)
-rw-r--r--.hgtags1
-rw-r--r--src/jdk/internal/dynalink/beans/AbstractJavaLinker.java7
-rw-r--r--src/jdk/internal/dynalink/beans/OverloadedMethod.java1
-rw-r--r--src/jdk/internal/dynalink/support/TypeUtilities.java22
-rw-r--r--src/jdk/nashorn/internal/runtime/linker/Bootstrap.java8
-rw-r--r--src/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java75
-rw-r--r--src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java60
-rw-r--r--test/script/basic/JDK-8020324.js.EXPECTED4
-rw-r--r--test/script/basic/JDK-8068573.js57
-rw-r--r--test/script/basic/JDK-8069002.js35
-rw-r--r--test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java39
-rw-r--r--test/src/jdk/nashorn/test/models/OverloadedSetter.java48
12 files changed, 276 insertions, 81 deletions
diff --git a/.hgtags b/.hgtags
index 507d7f8b..6cbd4791 100644
--- a/.hgtags
+++ b/.hgtags
@@ -363,6 +363,7 @@ e079f3f6d536510b1ab3589b1038d893d78302ac jdk8u40-b16
4d240320929f7b2247eeb97e43efe2370b70582e jdk8u40-b20
dbb663a9d9aa2807ef501c7d20f29415816a1973 jdk8u40-b21
f9f70a0f60f48fbb95275b6c1110cedf740c6177 jdk8u40-b22
+6ca090832d30fd0e46214ccc00816490ad75a8ab jdk8u40-b23
05a3614ed5276e5db2a73cce918be04b1a2922fb jdk8u45-b00
21ec16eb7e6346c78b4fa67ccd6d2a9c58f0b696 jdk8u45-b01
37b3ef9a07323afd2556d6837824db154cccc874 jdk8u45-b02
diff --git a/src/jdk/internal/dynalink/beans/AbstractJavaLinker.java b/src/jdk/internal/dynalink/beans/AbstractJavaLinker.java
index b8e8a3df..cf1b11d3 100644
--- a/src/jdk/internal/dynalink/beans/AbstractJavaLinker.java
+++ b/src/jdk/internal/dynalink/beans/AbstractJavaLinker.java
@@ -491,8 +491,9 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
// We want setters that conform to "Object(O, V)". Note, we aren't doing "R(O, V)" as it might not be
// valid for us to convert return values proactively. Also, since we don't know what setters will be
- // invoked, we'll conservatively presume Object return type.
- final MethodType type = callSiteDescriptor.getMethodType().changeReturnType(Object.class);
+ // invoked, we'll conservatively presume Object return type. The one exception is void return.
+ final MethodType origType = callSiteDescriptor.getMethodType();
+ final MethodType type = origType.returnType() == void.class ? origType : origType.changeReturnType(Object.class);
// What's below is basically:
// foldArguments(guardWithTest(isNotNull, invoke, null|nextComponent.invocation),
@@ -508,7 +509,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker {
// Bind property setter handle to the expected setter type and linker services. Type is
// MethodHandle(Object, String, Object)
final MethodHandle boundGetter = MethodHandles.insertArguments(getPropertySetterHandle, 0,
- CallSiteDescriptorFactory.dropParameterTypes(callSiteDescriptor, 1, 2), linkerServices);
+ callSiteDescriptor.changeMethodType(setterType), linkerServices);
// Cast getter to MethodHandle(O, N, V)
final MethodHandle typedGetter = linkerServices.asType(boundGetter, type.changeReturnType(
diff --git a/src/jdk/internal/dynalink/beans/OverloadedMethod.java b/src/jdk/internal/dynalink/beans/OverloadedMethod.java
index 70ec495a..c8d50072 100644
--- a/src/jdk/internal/dynalink/beans/OverloadedMethod.java
+++ b/src/jdk/internal/dynalink/beans/OverloadedMethod.java
@@ -123,7 +123,6 @@ class OverloadedMethod {
varArgMethods = new ArrayList<>(methodHandles.size());
final int argNum = callSiteType.parameterCount();
for(MethodHandle mh: methodHandles) {
- mh = mh.asType(mh.type().changeReturnType(commonRetType));
if(mh.isVarargsCollector()) {
final MethodHandle asFixed = mh.asFixedArity();
if(argNum == asFixed.type().parameterCount()) {
diff --git a/src/jdk/internal/dynalink/support/TypeUtilities.java b/src/jdk/internal/dynalink/support/TypeUtilities.java
index bf4771b2..78d42ab1 100644
--- a/src/jdk/internal/dynalink/support/TypeUtilities.java
+++ b/src/jdk/internal/dynalink/support/TypeUtilities.java
@@ -118,17 +118,13 @@ public class TypeUtilities {
public static Class<?> getCommonLosslessConversionType(final Class<?> c1, final Class<?> c2) {
if(c1 == c2) {
return c1;
+ } else if (c1 == void.class || c2 == void.class) {
+ return Object.class;
} else if(isConvertibleWithoutLoss(c2, c1)) {
return c1;
} else if(isConvertibleWithoutLoss(c1, c2)) {
return c2;
- }
- if(c1 == void.class) {
- return c2;
- } else if(c2 == void.class) {
- return c1;
- }
- if(c1.isPrimitive() && c2.isPrimitive()) {
+ } else if(c1.isPrimitive() && c2.isPrimitive()) {
if((c1 == byte.class && c2 == char.class) || (c1 == char.class && c2 == byte.class)) {
// byte + char = int
return int.class;
@@ -268,20 +264,24 @@ public class TypeUtilities {
}
/**
- * Determines whether a type can be converted to another without losing any
- * precision.
+ * Determines whether a type can be converted to another without losing any precision. As a special case,
+ * void is considered convertible only to Object and void, while anything can be converted to void. This
+ * is because a target type of void means we don't care about the value, so the conversion is always
+ * permissible.
*
* @param sourceType the source type
* @param targetType the target type
* @return true if lossless conversion is possible
*/
public static boolean isConvertibleWithoutLoss(final Class<?> sourceType, final Class<?> targetType) {
- if(targetType.isAssignableFrom(sourceType)) {
+ if(targetType.isAssignableFrom(sourceType) || targetType == void.class) {
return true;
}
if(sourceType.isPrimitive()) {
if(sourceType == void.class) {
- return false; // Void can't be losslessly represented by any type
+ // Void should be losslessly representable by Object, either as null or as a custom value that
+ // can be set with DynamicLinkerFactory.setAutoConversionStrategy.
+ return targetType == Object.class;
}
if(targetType.isPrimitive()) {
return isProperPrimitiveLosslessSubtype(sourceType, targetType);
diff --git a/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java b/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java
index 749c4728..cd4dd3b7 100644
--- a/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java
+++ b/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java
@@ -68,6 +68,8 @@ public final class Bootstrap {
private static final MethodHandleFunctionality MH = MethodHandleFactory.getFunctionality();
+ private static final MethodHandle VOID_TO_OBJECT = MH.constant(Object.class, ScriptRuntime.UNDEFINED);
+
/**
* The default dynalink relink threshold for megamorphisism is 8. In the case
* of object fields only, it is fine. However, with dual fields, in order to get
@@ -189,7 +191,7 @@ public final class Bootstrap {
* @return true if the obj is an instance of @FunctionalInterface interface
*/
public static boolean isFunctionalInterfaceObject(final Object obj) {
- return !JSType.isPrimitive(obj) && (NashornBottomLinker.getFunctionalInterfaceMethod(obj.getClass()) != null);
+ return !JSType.isPrimitive(obj) && (NashornBeansLinker.getFunctionalInterfaceMethod(obj.getClass()) != null);
}
/**
@@ -481,14 +483,16 @@ public final class Bootstrap {
private static MethodHandle unboxReturnType(final MethodHandle target, final MethodType newType) {
final MethodType targetType = target.type();
final Class<?> oldReturnType = targetType.returnType();
+ final Class<?> newReturnType = newType.returnType();
if (TypeUtilities.isWrapperType(oldReturnType)) {
- final Class<?> newReturnType = newType.returnType();
if (newReturnType.isPrimitive()) {
// The contract of setAutoConversionStrategy is such that the difference between newType and targetType
// can only be JLS method invocation conversions.
assert TypeUtilities.isMethodInvocationConvertible(oldReturnType, newReturnType);
return MethodHandles.explicitCastArguments(target, targetType.changeReturnType(newReturnType));
}
+ } else if (oldReturnType == void.class && newReturnType == Object.class) {
+ return MethodHandles.filterReturnValue(target, VOID_TO_OBJECT);
}
return target;
}
diff --git a/src/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java b/src/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java
index d5133cb3..da12af2d 100644
--- a/src/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java
+++ b/src/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java
@@ -25,20 +25,29 @@
package jdk.nashorn.internal.runtime.linker;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import jdk.internal.dynalink.CallSiteDescriptor;
import jdk.internal.dynalink.beans.BeansLinker;
import jdk.internal.dynalink.linker.ConversionComparator.Comparison;
import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.GuardingDynamicLinker;
import jdk.internal.dynalink.linker.LinkRequest;
import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.internal.dynalink.support.Guards;
import jdk.internal.dynalink.support.Lookup;
import jdk.nashorn.api.scripting.ScriptUtils;
import jdk.nashorn.internal.objects.NativeArray;
import jdk.nashorn.internal.runtime.ConsString;
+import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
import jdk.nashorn.internal.runtime.options.Options;
/**
@@ -68,19 +77,49 @@ public class NashornBeansLinker implements GuardingDynamicLinker {
FILTER_CONSSTRING = lookup.findOwnStatic("consStringFilter", Object.class, Object.class);
}
+ // cache of @FunctionalInterface method of implementor classes
+ private static final ClassValue<Method> FUNCTIONAL_IFACE_METHOD = new ClassValue<Method>() {
+ @Override
+ protected Method computeValue(final Class<?> type) {
+ return findFunctionalInterfaceMethod(type);
+ }
+ };
+
private final BeansLinker beansLinker = new BeansLinker();
@Override
public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
- if (linkRequest.getReceiver() instanceof ConsString) {
+ final Object self = linkRequest.getReceiver();
+ final CallSiteDescriptor desc = linkRequest.getCallSiteDescriptor();
+ if (self instanceof ConsString) {
// In order to treat ConsString like a java.lang.String we need a link request with a string receiver.
final Object[] arguments = linkRequest.getArguments();
arguments[0] = "";
- final LinkRequest forgedLinkRequest = linkRequest.replaceArguments(linkRequest.getCallSiteDescriptor(), arguments);
+ final LinkRequest forgedLinkRequest = linkRequest.replaceArguments(desc, arguments);
final GuardedInvocation invocation = getGuardedInvocation(beansLinker, forgedLinkRequest, linkerServices);
// If an invocation is found we add a filter that makes it work for both Strings and ConsStrings.
return invocation == null ? null : invocation.filterArguments(0, FILTER_CONSSTRING);
}
+
+ if (self != null && "call".equals(desc.getNameToken(CallSiteDescriptor.OPERATOR))) {
+ // Support dyn:call on any object that supports some @FunctionalInterface
+ // annotated interface. This way Java method, constructor references or
+ // implementations of java.util.function.* interfaces can be called as though
+ // those are script functions.
+ final Method m = getFunctionalInterfaceMethod(self.getClass());
+ if (m != null) {
+ final MethodType callType = desc.getMethodType();
+ // 'callee' and 'thiz' passed from script + actual arguments
+ if (callType.parameterCount() != m.getParameterCount() + 2) {
+ throw typeError("no.method.matches.args", ScriptRuntime.safeToString(self));
+ }
+ return new GuardedInvocation(
+ // drop 'thiz' passed from the script.
+ MH.dropArguments(desc.getLookup().unreflect(m), 1, callType.parameterType(1)),
+ Guards.getInstanceOfGuard(m.getDeclaringClass())).asTypeSafeReturn(
+ new NashornBeansLinkerServices(linkerServices), callType);
+ }
+ }
return getGuardedInvocation(beansLinker, linkRequest, linkerServices);
}
@@ -137,6 +176,38 @@ public class NashornBeansLinker implements GuardingDynamicLinker {
return arg instanceof ConsString ? arg.toString() : arg;
}
+ private static Method findFunctionalInterfaceMethod(final Class<?> clazz) {
+ if (clazz == null) {
+ return null;
+ }
+
+ for (final Class<?> iface : clazz.getInterfaces()) {
+ // check accessiblity up-front
+ if (! Context.isAccessibleClass(iface)) {
+ continue;
+ }
+
+ // check for @FunctionalInterface
+ if (iface.isAnnotationPresent(FunctionalInterface.class)) {
+ // return the first abstract method
+ for (final Method m : iface.getMethods()) {
+ if (Modifier.isAbstract(m.getModifiers())) {
+ return m;
+ }
+ }
+ }
+ }
+
+ // did not find here, try super class
+ return findFunctionalInterfaceMethod(clazz.getSuperclass());
+ }
+
+ // Returns @FunctionalInterface annotated interface's single abstract
+ // method. If not found, returns null.
+ static Method getFunctionalInterfaceMethod(final Class<?> clazz) {
+ return FUNCTIONAL_IFACE_METHOD.get(clazz);
+ }
+
private static class NashornBeansLinkerServices implements LinkerServices {
private final LinkerServices linkerServices;
diff --git a/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java b/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java
index 4ed6e3a2..2cbbf065 100644
--- a/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java
+++ b/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java
@@ -30,9 +30,6 @@ import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodType;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import jdk.internal.dynalink.CallSiteDescriptor;
@@ -45,7 +42,6 @@ import jdk.internal.dynalink.linker.LinkRequest;
import jdk.internal.dynalink.linker.LinkerServices;
import jdk.internal.dynalink.support.Guards;
import jdk.nashorn.internal.codegen.types.Type;
-import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.ScriptRuntime;
import jdk.nashorn.internal.runtime.UnwarrantedOptimismException;
@@ -95,22 +91,6 @@ final class NashornBottomLinker implements GuardingDynamicLinker, GuardingTypeCo
}
throw typeError("not.a.function", ScriptRuntime.safeToString(self));
case "call":
- // Support dyn:call on any object that supports some @FunctionalInterface
- // annotated interface. This way Java method, constructor references or
- // implementations of java.util.function.* interfaces can be called as though
- // those are script functions.
- final Method m = getFunctionalInterfaceMethod(self.getClass());
- if (m != null) {
- final MethodType callType = desc.getMethodType();
- // 'callee' and 'thiz' passed from script + actual arguments
- if (callType.parameterCount() != m.getParameterCount() + 2) {
- throw typeError("no.method.matches.args", ScriptRuntime.safeToString(self));
- }
- return Bootstrap.asTypeSafeReturn(new GuardedInvocation(
- // drop 'thiz' passed from the script.
- MH.dropArguments(desc.getLookup().unreflect(m), 1, callType.parameterType(1)),
- Guards.getInstanceOfGuard(m.getDeclaringClass())), linkerServices, desc);
- }
if(BeansLinker.isDynamicConstructor(self)) {
throw typeError("constructor.requires.new", ScriptRuntime.safeToString(self));
}
@@ -218,44 +198,4 @@ final class NashornBottomLinker implements GuardingDynamicLinker, GuardingTypeCo
}
return ScriptRuntime.safeToString(linkRequest.getArguments()[1]);
}
-
- // cache of @FunctionalInterface method of implementor classes
- private static final ClassValue<Method> FUNCTIONAL_IFACE_METHOD = new ClassValue<Method>() {
- @Override
- protected Method computeValue(final Class<?> type) {
- return findFunctionalInterfaceMethod(type);
- }
-
- private Method findFunctionalInterfaceMethod(final Class<?> clazz) {
- if (clazz == null) {
- return null;
- }
-
- for (final Class<?> iface : clazz.getInterfaces()) {
- // check accessiblity up-front
- if (! Context.isAccessibleClass(iface)) {
- continue;
- }
-
- // check for @FunctionalInterface
- if (iface.isAnnotationPresent(FunctionalInterface.class)) {
- // return the first abstract method
- for (final Method m : iface.getMethods()) {
- if (Modifier.isAbstract(m.getModifiers())) {
- return m;
- }
- }
- }
- }
-
- // did not find here, try super class
- return findFunctionalInterfaceMethod(clazz.getSuperclass());
- }
- };
-
- // Returns @FunctionalInterface annotated interface's single abstract
- // method. If not found, returns null.
- static Method getFunctionalInterfaceMethod(final Class<?> clazz) {
- return FUNCTIONAL_IFACE_METHOD.get(clazz);
- }
}
diff --git a/test/script/basic/JDK-8020324.js.EXPECTED b/test/script/basic/JDK-8020324.js.EXPECTED
index 500f46b9..9ebae802 100644
--- a/test/script/basic/JDK-8020324.js.EXPECTED
+++ b/test/script/basic/JDK-8020324.js.EXPECTED
@@ -17,7 +17,7 @@ bean.readWrite: 17
bean.readWrite = 18: 18
obj1.readWrite: 18
obj1.getReadWrite(): 18
-obj1.setReadWrite(19): null
+obj1.setReadWrite(19): undefined
obj1.readWrite: 19
bean.readWrite: 19
@@ -52,7 +52,7 @@ PropertyBind.staticReadWrite: 25
PropertyBind.staticReadWrite = 26: 26
obj2.staticReadWrite: 26
obj2.getStaticReadWrite(): 26
-obj2.setStaticReadWrite(27): null
+obj2.setStaticReadWrite(27): undefined
obj2.staticReadWrite: 27
PropertyBind.staticReadWrite: 27
diff --git a/test/script/basic/JDK-8068573.js b/test/script/basic/JDK-8068573.js
new file mode 100644
index 00000000..73f71582
--- /dev/null
+++ b/test/script/basic/JDK-8068573.js
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8068573: POJO setter using [] syntax throws an exception
+ *
+ * @test
+ * @run
+ */
+
+// Invoke a setter using []. It's important that the setter returns void.
+var pb = new (Java.type("jdk.nashorn.test.models.PropertyBind"))
+var n = "writeOnly";
+pb[n] = 2;
+Assert.assertEquals(pb.peekWriteOnly(), 2);
+
+// Invoke an overloaded setter using []. It's important that one of the
+// overloads returns void.
+var os = new (Java.type("jdk.nashorn.test.models.OverloadedSetter"))
+var n2 = "color";
+os[n2] = 3; // exercise int overload
+Assert.assertEquals(os.peekColor(), "3");
+os[n2] = "blue"; // exercise string overload
+Assert.assertEquals(os.peekColor(), "blue");
+for each(var x in [42, "42"]) {
+ os[n2] = x; // exercise both overloads in the same call site
+ Assert.assertEquals(os.peekColor(), "42");
+}
+
+// Invoke an overloaded method using [], repeatedly in the same call
+// site. It's important that one of the overloads returns void.
+var n3="foo";
+var param=["xyz", 1, "zyx", 2];
+var expected=["boo", void 0, "boo", void 0];
+for(var i in param) {
+ Assert.assertEquals(os[n3](param[i]), expected[i]);
+}
diff --git a/test/script/basic/JDK-8069002.js b/test/script/basic/JDK-8069002.js
new file mode 100644
index 00000000..29d75516
--- /dev/null
+++ b/test/script/basic/JDK-8069002.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8069002: NPE on invoking null (8068889 regression)
+ *
+ * @test
+ * @run
+ */
+
+try {
+ null();
+} catch (e) {
+ Assert.assertTrue(e instanceof TypeError);
+}
diff --git a/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java b/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java
index a066d6b3..ef4996f1 100644
--- a/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java
+++ b/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java
@@ -29,12 +29,16 @@ import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
+
import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
+import java.util.function.Function;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.Invocable;
@@ -668,6 +672,41 @@ public class ScriptEngineTest {
assertEquals("helloworld", inv.invokeMethod(ctx.get(), "join", ""));
}
+ // @bug JDK-8068889: ConsString arguments to a functional interface wasn't converted to string.
+ @Test
+ public void functionalInterfaceStringTest() throws Exception {
+ final ScriptEngineManager manager = new ScriptEngineManager();
+ final ScriptEngine e = manager.getEngineByName("nashorn");
+ final AtomicBoolean invoked = new AtomicBoolean(false);
+ e.put("f", new Function<String, String>() {
+ @Override
+ public String apply(String t) {
+ invoked.set(true);
+ return t;
+ }
+ });
+ assertEquals(e.eval("var x = 'a'; x += 'b'; f(x)"), "ab");
+ assertTrue(invoked.get());
+ }
+
+ // @bug JDK-8068889: ScriptObject arguments to a functional interface wasn't converted to a mirror.
+ @Test
+ public void functionalInterfaceObjectTest() throws Exception {
+ final ScriptEngineManager manager = new ScriptEngineManager();
+ final ScriptEngine e = manager.getEngineByName("nashorn");
+ final AtomicBoolean invoked = new AtomicBoolean(false);
+ e.put("c", new Consumer<Object>() {
+ @Override
+ public void accept(Object t) {
+ assertTrue(t instanceof ScriptObjectMirror);
+ assertEquals(((ScriptObjectMirror)t).get("a"), "xyz");
+ invoked.set(true);
+ }
+ });
+ e.eval("var x = 'xy'; x += 'z';c({a:x})");
+ assertTrue(invoked.get());
+ }
+
private static void checkProperty(final ScriptEngine e, final String name)
throws ScriptException {
final String value = System.getProperty(name);
diff --git a/test/src/jdk/nashorn/test/models/OverloadedSetter.java b/test/src/jdk/nashorn/test/models/OverloadedSetter.java
new file mode 100644
index 00000000..810ae2f1
--- /dev/null
+++ b/test/src/jdk/nashorn/test/models/OverloadedSetter.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.nashorn.test.models;
+
+public class OverloadedSetter {
+ private String color;
+
+ public void setColor(final int x) {
+ this.color = Integer.toString(x);
+ }
+
+ public void setColor(final String x) {
+ this.color = x;
+ }
+
+ public String peekColor() {
+ return color;
+ }
+
+ public void foo(final int x) {
+ }
+
+ public String foo(final String x) {
+ return "boo";
+ }
+}