Merge
authorlana
Thu, 26 May 2016 17:19:03 +0000
changeset 38597 3e6c168b4edb
parent 38593 a50587a3294c (current diff)
parent 38596 9151a113789d (diff)
child 38598 6a1b521db882
Merge
--- a/nashorn/samples/test.js	Thu May 26 16:02:18 2016 +0000
+++ b/nashorn/samples/test.js	Thu May 26 17:19:03 2016 +0000
@@ -31,4 +31,4 @@
 
 print("Hello World");
 var System = Java.type("java.lang.System");
-print(System.getProperty("jdk.launcher.patch.0"));
+print(System.getProperty("java.home"));
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeArray.java	Thu May 26 16:02:18 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeArray.java	Thu May 26 17:19:03 2016 +0000
@@ -238,7 +238,7 @@
                     @Override
                     public MethodHandle call() {
                         return Bootstrap.createDynamicCallInvoker(double.class,
-                            ScriptFunction.class, Object.class, Object.class, Object.class);
+                            Object.class, Object.class, Object.class, Object.class);
                     }
                 });
     }
@@ -1210,23 +1210,23 @@
         return copy;
     }
 
-    private static ScriptFunction compareFunction(final Object comparefn) {
+    private static Object compareFunction(final Object comparefn) {
         if (comparefn == ScriptRuntime.UNDEFINED) {
             return null;
         }
 
-        if (! (comparefn instanceof ScriptFunction)) {
+        if (!Bootstrap.isCallable(comparefn)) {
             throw typeError("not.a.function", ScriptRuntime.safeToString(comparefn));
         }
 
-        return (ScriptFunction)comparefn;
+        return comparefn;
     }
 
     private static Object[] sort(final Object[] array, final Object comparefn) {
-        final ScriptFunction cmp = compareFunction(comparefn);
+        final Object cmp = compareFunction(comparefn);
 
         final List<Object> list = Arrays.asList(array);
-        final Object cmpThis = cmp == null || cmp.isStrict() ? ScriptRuntime.UNDEFINED : Global.instance();
+        final Object cmpThis = cmp == null || Bootstrap.isStrictCallable(cmp) ? ScriptRuntime.UNDEFINED : Global.instance();
 
         try {
             Collections.sort(list, new Comparator<Object>() {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJSON.java	Thu May 26 16:02:18 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJSON.java	Thu May 26 17:19:03 2016 +0000
@@ -47,7 +47,6 @@
 import jdk.nashorn.internal.runtime.JSONFunctions;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.PropertyMap;
-import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeRegExp.java	Thu May 26 16:02:18 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeRegExp.java	Thu May 26 17:19:03 2016 +0000
@@ -45,7 +45,6 @@
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.ParserException;
 import jdk.nashorn.internal.runtime.PropertyMap;
-import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
@@ -655,7 +654,7 @@
      * @param replacement Replacement string.
      * @return String with substitutions.
      */
-    String replace(final String string, final String replacement, final ScriptFunction function) throws Throwable {
+    String replace(final String string, final String replacement, final Object function) throws Throwable {
         final RegExpMatcher matcher = regexp.match(string);
 
         if (matcher == null) {
@@ -671,7 +670,7 @@
             sb.append(string, 0, matcher.start());
 
             if (function != null) {
-                final Object self = function.isStrict() ? UNDEFINED : Global.instance();
+                final Object self = Bootstrap.isStrictCallable(function) ? UNDEFINED : Global.instance();
                 sb.append(callReplaceValue(getReplaceValueInvoker(), function, self, matcher, string));
             } else {
                 appendReplacement(matcher, string, replacement, sb);
@@ -691,7 +690,7 @@
         final StringBuilder sb = new StringBuilder();
 
         final MethodHandle invoker = function == null ? null : getReplaceValueInvoker();
-        final Object self = function == null || function.isStrict() ? UNDEFINED : Global.instance();
+        final Object self = function == null || Bootstrap.isStrictCallable(function) ? UNDEFINED : Global.instance();
 
         do {
             sb.append(string, thisIndex, matcher.start());
@@ -807,12 +806,12 @@
                 new Callable<MethodHandle>() {
                     @Override
                     public MethodHandle call() {
-                        return Bootstrap.createDynamicCallInvoker(String.class, ScriptFunction.class, Object.class, Object[].class);
+                        return Bootstrap.createDynamicCallInvoker(String.class, Object.class, Object.class, Object[].class);
                     }
                 });
     }
 
-    private String callReplaceValue(final MethodHandle invoker, final ScriptFunction function, final Object self, final RegExpMatcher matcher, final String string) throws Throwable {
+    private String callReplaceValue(final MethodHandle invoker, final Object function, final Object self, final RegExpMatcher matcher, final String string) throws Throwable {
         final Object[] groups = groups(matcher);
         final Object[] args   = Arrays.copyOf(groups, groups.length + 2);
 
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeString.java	Thu May 26 16:02:18 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeString.java	Thu May 26 17:19:03 2016 +0000
@@ -58,10 +58,10 @@
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.OptimisticBuiltins;
 import jdk.nashorn.internal.runtime.PropertyMap;
-import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
+import jdk.nashorn.internal.runtime.linker.Bootstrap;
 import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
 import jdk.nashorn.internal.runtime.linker.NashornGuards;
 import jdk.nashorn.internal.runtime.linker.PrimitiveLookup;
@@ -743,8 +743,8 @@
             nativeRegExp = NativeRegExp.flatRegExp(JSType.toString(string));
         }
 
-        if (replacement instanceof ScriptFunction) {
-            return nativeRegExp.replace(str, "", (ScriptFunction)replacement);
+        if (Bootstrap.isCallable(replacement)) {
+            return nativeRegExp.replace(str, "", replacement);
         }
 
         return nativeRegExp.replace(str, JSType.toString(replacement), null);
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeWeakMap.java	Thu May 26 16:02:18 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeWeakMap.java	Thu May 26 17:19:03 2016 +0000
@@ -31,7 +31,6 @@
 import jdk.nashorn.internal.objects.annotations.Constructor;
 import jdk.nashorn.internal.objects.annotations.Function;
 import jdk.nashorn.internal.objects.annotations.ScriptClass;
-import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.PropertyMap;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeWeakSet.java	Thu May 26 16:02:18 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeWeakSet.java	Thu May 26 17:19:03 2016 +0000
@@ -31,7 +31,6 @@
 import jdk.nashorn.internal.objects.annotations.Constructor;
 import jdk.nashorn.internal.objects.annotations.Function;
 import jdk.nashorn.internal.objects.annotations.ScriptClass;
-import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.PropertyMap;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/JSONFunctions.java	Thu May 26 16:02:18 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/JSONFunctions.java	Thu May 26 17:19:03 2016 +0000
@@ -46,7 +46,7 @@
                     @Override
                     public MethodHandle call() {
                         return Bootstrap.createDynamicCallInvoker(Object.class,
-                            ScriptFunction.class, ScriptObject.class, String.class, Object.class);
+                            Object.class, Object.class, String.class, Object.class);
                     }
                 });
     }
@@ -90,16 +90,16 @@
 
     // apply 'reviver' function if available
     private static Object applyReviver(final Global global, final Object unfiltered, final Object reviver) {
-        if (reviver instanceof ScriptFunction) {
+        if (Bootstrap.isCallable(reviver)) {
             final ScriptObject root = global.newObject();
             root.addOwnProperty("", Property.WRITABLE_ENUMERABLE_CONFIGURABLE, unfiltered);
-            return walk(root, "", (ScriptFunction)reviver);
+            return walk(root, "", reviver);
         }
         return unfiltered;
     }
 
     // This is the abstract "Walk" operation from the spec.
-    private static Object walk(final ScriptObject holder, final Object name, final ScriptFunction reviver) {
+    private static Object walk(final ScriptObject holder, final Object name, final Object reviver) {
         final Object val = holder.get(name);
         if (val instanceof ScriptObject) {
             final ScriptObject     valueObj = (ScriptObject)val;
@@ -131,7 +131,7 @@
 
         try {
              // Object.class, ScriptFunction.class, ScriptObject.class, String.class, Object.class);
-             return getREVIVER_INVOKER().invokeExact(reviver, holder, JSType.toString(name), val);
+             return getREVIVER_INVOKER().invokeExact(reviver, (Object)holder, JSType.toString(name), val);
         } catch(Error|RuntimeException t) {
             throw t;
         } catch(final Throwable t) {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java	Thu May 26 16:02:18 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java	Thu May 26 17:19:03 2016 +0000
@@ -171,7 +171,9 @@
             return ((JSObject)callable).isStrictFunction();
         } else if (callable instanceof BoundCallable) {
             return isStrictCallable(((BoundCallable)callable).getCallable());
-        } else if (BeansLinker.isDynamicMethod(callable) || callable instanceof StaticClass) {
+        } else if (BeansLinker.isDynamicMethod(callable) ||
+                callable instanceof StaticClass ||
+                isFunctionalInterfaceObject(callable)) {
             return false;
         }
         throw notFunction(callable);
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java	Thu May 26 16:02:18 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java	Thu May 26 17:19:03 2016 +0000
@@ -186,7 +186,7 @@
             if (iface.isAnnotationPresent(FunctionalInterface.class)) {
                 // return the first abstract method
                 for (final Method m : iface.getMethods()) {
-                    if (Modifier.isAbstract(m.getModifiers())) {
+                    if (Modifier.isAbstract(m.getModifiers()) && !isOverridableObjectMethod(m)) {
                         return m.getName();
                     }
                 }
@@ -197,6 +197,23 @@
         return findFunctionalInterfaceMethodName(clazz.getSuperclass());
     }
 
+    // is this an overridable java.lang.Object method?
+    private static boolean isOverridableObjectMethod(final Method m) {
+        switch (m.getName()) {
+            case "equals":
+                if (m.getReturnType() == boolean.class) {
+                    final Class<?>[] params = m.getParameterTypes();
+                    return params.length == 1 && params[0] == Object.class;
+                }
+                return false;
+            case "hashCode":
+                return m.getReturnType() == int.class && m.getParameterCount() == 0;
+            case "toString":
+                return m.getReturnType() == String.class && m.getParameterCount() == 0;
+        }
+        return false;
+    }
+
     // Returns @FunctionalInterface annotated interface's single abstract
     // method name. If not found, returns null.
     static String getFunctionalInterfaceMethodName(final Class<?> clazz) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8157680.js	Thu May 26 17:19:03 2016 +0000
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2016, 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-8157680: Callback parameter of any JS builtin implementation should accept any Callable
+ *
+ * @option -scripting
+ * @test
+ * @run
+ */
+
+var SM = Java.type("javax.script.ScriptEngineManager")
+var engine = new SM().getEngineByName("nashorn")
+
+engine.put("output", print);
+var reviver = engine.eval(<<EOF
+function(name, value) {
+   if (name == "") return value
+   output(name + " = " + value)
+   return value
+}
+EOF)
+
+// reviver function from mirror world!
+JSON.parse('{ "foo" : 44, "bar" : "hello" }', reviver)
+
+var AJO = Java.type("jdk.nashorn.api.scripting.AbstractJSObject")
+// reviver function as a JSObject function
+JSON.parse('{ "nashorn" : "hello" }', new AJO() {
+    isFunction: function() true,
+    call: function(thiz, args) {
+        var name = args[0], value = args[1]
+        if (name == "") return value
+        print(name + " -> " + value)
+        return value
+    } 
+})
+
+// compare function from the mirror world
+var arr = [34,567,-3, 53].sort(engine.eval(<<EOF
+    function(x, y) x < y? -1 : ((x > y)? 1 : 0)
+EOF))
+print(arr)
+
+// compare function as a JSObject function
+arr = [34,57,-3, 53, 670, 33].sort(new AJO() {
+    isFunction: function() true,
+    call: function(thiz, args) {
+        var x = args[0], y = args[1]
+        return x < y? -1 : ((x > y)? 1 : 0)
+    }
+})
+print(arr)
+
+// replacer function from mirror world
+var str = "hello".replace(/l/g, engine.eval(<<EOF
+    function() "_"
+EOF))
+print(str)
+
+// replacer function as a JSObject function
+str = "hello".replace(/[el]/g, new AJO() {
+    isFunction: function() true,
+    call: function(thiz, args) {
+        var match = args[0]
+        return match.toUpperCase()
+    }
+})
+print(str)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8157680.js.EXPECTED	Thu May 26 17:19:03 2016 +0000
@@ -0,0 +1,7 @@
+foo = 44
+bar = hello
+nashorn -> hello
+-3,34,53,567
+-3,33,34,53,57,670
+he__o
+hELLo
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8157819.js	Thu May 26 17:19:03 2016 +0000
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016, 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-8157819: TypeError when a java.util.Comparator object is invoked as a function
+ *
+ * @test
+ * @run
+ */
+
+var compare = java.util.Comparator.naturalOrder()
+Assert.assertTrue(compare("nashorn", "ecmascript") > 0)
+Assert.assertTrue(compare("abc", "xyz") < 0)
+Assert.assertTrue(compare("hello", "hello") == 0)
+
+var rcompare = java.util.Comparator.reverseOrder()
+Assert.assertTrue(rcompare("nashorn", "ecmascript") < 0)
+Assert.assertTrue(rcompare("abc", "xyz") > 0)
+Assert.assertTrue(rcompare("hello", "hello") == 0)
+
+var arr = [ "nashorn", "JavaScript", "ECMAScript", "ecmascript", "js" ]
+Assert.assertEquals(arr.sort(compare).join(),
+    "ECMAScript,JavaScript,ecmascript,js,nashorn")
+Assert.assertEquals(arr.sort(rcompare).join(),
+    "nashorn,js,ecmascript,JavaScript,ECMAScript")
+