Skip to content

Commit 0933ac4

Browse files
author
duke
committed
Merge
2 parents 20d6588 + 596f1d1 commit 0933ac4

File tree

14 files changed

+184
-26
lines changed

14 files changed

+184
-26
lines changed

nashorn/.hgtags

+1
Original file line numberDiff line numberDiff line change
@@ -353,3 +353,4 @@ ba21793a0e4816283cc0ecdab5142a4959363529 jdk-9+114
353353
5267e91811614bac129817e566f730e9d63cf22a jdk-9+117
354354
05679aac2f7ec3d8dd2a96d7e7899906224bf5cf jdk-9+118
355355
621ad507bf9b07e7c6da2150aa619fe7e78ec5a0 jdk-9+119
356+
7ab7fc00b147e5b50d6bd5516147680f11c0b165 jdk-9+120

nashorn/samples/test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,4 @@
3131

3232
print("Hello World");
3333
var System = Java.type("java.lang.System");
34-
print(System.getProperty("jdk.launcher.patch.0"));
34+
print(System.getProperty("java.home"));

nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeArray.java

+6-6
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ private static MethodHandle getCALL_CMP() {
238238
@Override
239239
public MethodHandle call() {
240240
return Bootstrap.createDynamicCallInvoker(double.class,
241-
ScriptFunction.class, Object.class, Object.class, Object.class);
241+
Object.class, Object.class, Object.class, Object.class);
242242
}
243243
});
244244
}
@@ -1210,23 +1210,23 @@ public static Object slice(final Object self, final Object start, final Object e
12101210
return copy;
12111211
}
12121212

1213-
private static ScriptFunction compareFunction(final Object comparefn) {
1213+
private static Object compareFunction(final Object comparefn) {
12141214
if (comparefn == ScriptRuntime.UNDEFINED) {
12151215
return null;
12161216
}
12171217

1218-
if (! (comparefn instanceof ScriptFunction)) {
1218+
if (!Bootstrap.isCallable(comparefn)) {
12191219
throw typeError("not.a.function", ScriptRuntime.safeToString(comparefn));
12201220
}
12211221

1222-
return (ScriptFunction)comparefn;
1222+
return comparefn;
12231223
}
12241224

12251225
private static Object[] sort(final Object[] array, final Object comparefn) {
1226-
final ScriptFunction cmp = compareFunction(comparefn);
1226+
final Object cmp = compareFunction(comparefn);
12271227

12281228
final List<Object> list = Arrays.asList(array);
1229-
final Object cmpThis = cmp == null || cmp.isStrict() ? ScriptRuntime.UNDEFINED : Global.instance();
1229+
final Object cmpThis = cmp == null || Bootstrap.isStrictCallable(cmp) ? ScriptRuntime.UNDEFINED : Global.instance();
12301230

12311231
try {
12321232
Collections.sort(list, new Comparator<Object>() {

nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJSON.java

-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
import jdk.nashorn.internal.runtime.JSONFunctions;
4848
import jdk.nashorn.internal.runtime.JSType;
4949
import jdk.nashorn.internal.runtime.PropertyMap;
50-
import jdk.nashorn.internal.runtime.ScriptFunction;
5150
import jdk.nashorn.internal.runtime.ScriptObject;
5251
import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
5352
import jdk.nashorn.internal.runtime.linker.Bootstrap;

nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeRegExp.java

+5-6
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545
import jdk.nashorn.internal.runtime.JSType;
4646
import jdk.nashorn.internal.runtime.ParserException;
4747
import jdk.nashorn.internal.runtime.PropertyMap;
48-
import jdk.nashorn.internal.runtime.ScriptFunction;
4948
import jdk.nashorn.internal.runtime.ScriptObject;
5049
import jdk.nashorn.internal.runtime.ScriptRuntime;
5150
import jdk.nashorn.internal.runtime.linker.Bootstrap;
@@ -655,7 +654,7 @@ public boolean test(final String string) {
655654
* @param replacement Replacement string.
656655
* @return String with substitutions.
657656
*/
658-
String replace(final String string, final String replacement, final ScriptFunction function) throws Throwable {
657+
String replace(final String string, final String replacement, final Object function) throws Throwable {
659658
final RegExpMatcher matcher = regexp.match(string);
660659

661660
if (matcher == null) {
@@ -671,7 +670,7 @@ String replace(final String string, final String replacement, final ScriptFuncti
671670
sb.append(string, 0, matcher.start());
672671

673672
if (function != null) {
674-
final Object self = function.isStrict() ? UNDEFINED : Global.instance();
673+
final Object self = Bootstrap.isStrictCallable(function) ? UNDEFINED : Global.instance();
675674
sb.append(callReplaceValue(getReplaceValueInvoker(), function, self, matcher, string));
676675
} else {
677676
appendReplacement(matcher, string, replacement, sb);
@@ -691,7 +690,7 @@ String replace(final String string, final String replacement, final ScriptFuncti
691690
final StringBuilder sb = new StringBuilder();
692691

693692
final MethodHandle invoker = function == null ? null : getReplaceValueInvoker();
694-
final Object self = function == null || function.isStrict() ? UNDEFINED : Global.instance();
693+
final Object self = function == null || Bootstrap.isStrictCallable(function) ? UNDEFINED : Global.instance();
695694

696695
do {
697696
sb.append(string, thisIndex, matcher.start());
@@ -807,12 +806,12 @@ private static MethodHandle getReplaceValueInvoker() {
807806
new Callable<MethodHandle>() {
808807
@Override
809808
public MethodHandle call() {
810-
return Bootstrap.createDynamicCallInvoker(String.class, ScriptFunction.class, Object.class, Object[].class);
809+
return Bootstrap.createDynamicCallInvoker(String.class, Object.class, Object.class, Object[].class);
811810
}
812811
});
813812
}
814813

815-
private String callReplaceValue(final MethodHandle invoker, final ScriptFunction function, final Object self, final RegExpMatcher matcher, final String string) throws Throwable {
814+
private String callReplaceValue(final MethodHandle invoker, final Object function, final Object self, final RegExpMatcher matcher, final String string) throws Throwable {
816815
final Object[] groups = groups(matcher);
817816
final Object[] args = Arrays.copyOf(groups, groups.length + 2);
818817

nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeString.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,10 @@
5858
import jdk.nashorn.internal.runtime.JSType;
5959
import jdk.nashorn.internal.runtime.OptimisticBuiltins;
6060
import jdk.nashorn.internal.runtime.PropertyMap;
61-
import jdk.nashorn.internal.runtime.ScriptFunction;
6261
import jdk.nashorn.internal.runtime.ScriptObject;
6362
import jdk.nashorn.internal.runtime.ScriptRuntime;
6463
import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
64+
import jdk.nashorn.internal.runtime.linker.Bootstrap;
6565
import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
6666
import jdk.nashorn.internal.runtime.linker.NashornGuards;
6767
import jdk.nashorn.internal.runtime.linker.PrimitiveLookup;
@@ -743,8 +743,8 @@ public static String replace(final Object self, final Object string, final Objec
743743
nativeRegExp = NativeRegExp.flatRegExp(JSType.toString(string));
744744
}
745745

746-
if (replacement instanceof ScriptFunction) {
747-
return nativeRegExp.replace(str, "", (ScriptFunction)replacement);
746+
if (Bootstrap.isCallable(replacement)) {
747+
return nativeRegExp.replace(str, "", replacement);
748748
}
749749

750750
return nativeRegExp.replace(str, JSType.toString(replacement), null);

nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeWeakMap.java

-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import jdk.nashorn.internal.objects.annotations.Constructor;
3232
import jdk.nashorn.internal.objects.annotations.Function;
3333
import jdk.nashorn.internal.objects.annotations.ScriptClass;
34-
import jdk.nashorn.internal.runtime.JSType;
3534
import jdk.nashorn.internal.runtime.PropertyMap;
3635
import jdk.nashorn.internal.runtime.ScriptObject;
3736
import jdk.nashorn.internal.runtime.ScriptRuntime;

nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeWeakSet.java

-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import jdk.nashorn.internal.objects.annotations.Constructor;
3232
import jdk.nashorn.internal.objects.annotations.Function;
3333
import jdk.nashorn.internal.objects.annotations.ScriptClass;
34-
import jdk.nashorn.internal.runtime.JSType;
3534
import jdk.nashorn.internal.runtime.PropertyMap;
3635
import jdk.nashorn.internal.runtime.ScriptObject;
3736
import jdk.nashorn.internal.runtime.ScriptRuntime;

nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/JSONFunctions.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ private static MethodHandle getREVIVER_INVOKER() {
4646
@Override
4747
public MethodHandle call() {
4848
return Bootstrap.createDynamicCallInvoker(Object.class,
49-
ScriptFunction.class, ScriptObject.class, String.class, Object.class);
49+
Object.class, Object.class, String.class, Object.class);
5050
}
5151
});
5252
}
@@ -90,16 +90,16 @@ public static Object parse(final Object text, final Object reviver) {
9090

9191
// apply 'reviver' function if available
9292
private static Object applyReviver(final Global global, final Object unfiltered, final Object reviver) {
93-
if (reviver instanceof ScriptFunction) {
93+
if (Bootstrap.isCallable(reviver)) {
9494
final ScriptObject root = global.newObject();
9595
root.addOwnProperty("", Property.WRITABLE_ENUMERABLE_CONFIGURABLE, unfiltered);
96-
return walk(root, "", (ScriptFunction)reviver);
96+
return walk(root, "", reviver);
9797
}
9898
return unfiltered;
9999
}
100100

101101
// This is the abstract "Walk" operation from the spec.
102-
private static Object walk(final ScriptObject holder, final Object name, final ScriptFunction reviver) {
102+
private static Object walk(final ScriptObject holder, final Object name, final Object reviver) {
103103
final Object val = holder.get(name);
104104
if (val instanceof ScriptObject) {
105105
final ScriptObject valueObj = (ScriptObject)val;
@@ -131,7 +131,7 @@ private static Object walk(final ScriptObject holder, final Object name, final S
131131

132132
try {
133133
// Object.class, ScriptFunction.class, ScriptObject.class, String.class, Object.class);
134-
return getREVIVER_INVOKER().invokeExact(reviver, holder, JSType.toString(name), val);
134+
return getREVIVER_INVOKER().invokeExact(reviver, (Object)holder, JSType.toString(name), val);
135135
} catch(Error|RuntimeException t) {
136136
throw t;
137137
} catch(final Throwable t) {

nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,9 @@ public static boolean isStrictCallable(final Object callable) {
171171
return ((JSObject)callable).isStrictFunction();
172172
} else if (callable instanceof BoundCallable) {
173173
return isStrictCallable(((BoundCallable)callable).getCallable());
174-
} else if (BeansLinker.isDynamicMethod(callable) || callable instanceof StaticClass) {
174+
} else if (BeansLinker.isDynamicMethod(callable) ||
175+
callable instanceof StaticClass ||
176+
isFunctionalInterfaceObject(callable)) {
175177
return false;
176178
}
177179
throw notFunction(callable);

nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java

+18-1
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ private static String findFunctionalInterfaceMethodName(final Class<?> clazz) {
186186
if (iface.isAnnotationPresent(FunctionalInterface.class)) {
187187
// return the first abstract method
188188
for (final Method m : iface.getMethods()) {
189-
if (Modifier.isAbstract(m.getModifiers())) {
189+
if (Modifier.isAbstract(m.getModifiers()) && !isOverridableObjectMethod(m)) {
190190
return m.getName();
191191
}
192192
}
@@ -197,6 +197,23 @@ private static String findFunctionalInterfaceMethodName(final Class<?> clazz) {
197197
return findFunctionalInterfaceMethodName(clazz.getSuperclass());
198198
}
199199

200+
// is this an overridable java.lang.Object method?
201+
private static boolean isOverridableObjectMethod(final Method m) {
202+
switch (m.getName()) {
203+
case "equals":
204+
if (m.getReturnType() == boolean.class) {
205+
final Class<?>[] params = m.getParameterTypes();
206+
return params.length == 1 && params[0] == Object.class;
207+
}
208+
return false;
209+
case "hashCode":
210+
return m.getReturnType() == int.class && m.getParameterCount() == 0;
211+
case "toString":
212+
return m.getReturnType() == String.class && m.getParameterCount() == 0;
213+
}
214+
return false;
215+
}
216+
200217
// Returns @FunctionalInterface annotated interface's single abstract
201218
// method name. If not found, returns null.
202219
static String getFunctionalInterfaceMethodName(final Class<?> clazz) {
+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/**
25+
* JDK-8157680: Callback parameter of any JS builtin implementation should accept any Callable
26+
*
27+
* @option -scripting
28+
* @test
29+
* @run
30+
*/
31+
32+
var SM = Java.type("javax.script.ScriptEngineManager")
33+
var engine = new SM().getEngineByName("nashorn")
34+
35+
engine.put("output", print);
36+
var reviver = engine.eval(<<EOF
37+
function(name, value) {
38+
if (name == "") return value
39+
output(name + " = " + value)
40+
return value
41+
}
42+
EOF)
43+
44+
// reviver function from mirror world!
45+
JSON.parse('{ "foo" : 44, "bar" : "hello" }', reviver)
46+
47+
var AJO = Java.type("jdk.nashorn.api.scripting.AbstractJSObject")
48+
// reviver function as a JSObject function
49+
JSON.parse('{ "nashorn" : "hello" }', new AJO() {
50+
isFunction: function() true,
51+
call: function(thiz, args) {
52+
var name = args[0], value = args[1]
53+
if (name == "") return value
54+
print(name + " -> " + value)
55+
return value
56+
}
57+
})
58+
59+
// compare function from the mirror world
60+
var arr = [34,567,-3, 53].sort(engine.eval(<<EOF
61+
function(x, y) x < y? -1 : ((x > y)? 1 : 0)
62+
EOF))
63+
print(arr)
64+
65+
// compare function as a JSObject function
66+
arr = [34,57,-3, 53, 670, 33].sort(new AJO() {
67+
isFunction: function() true,
68+
call: function(thiz, args) {
69+
var x = args[0], y = args[1]
70+
return x < y? -1 : ((x > y)? 1 : 0)
71+
}
72+
})
73+
print(arr)
74+
75+
// replacer function from mirror world
76+
var str = "hello".replace(/l/g, engine.eval(<<EOF
77+
function() "_"
78+
EOF))
79+
print(str)
80+
81+
// replacer function as a JSObject function
82+
str = "hello".replace(/[el]/g, new AJO() {
83+
isFunction: function() true,
84+
call: function(thiz, args) {
85+
var match = args[0]
86+
return match.toUpperCase()
87+
}
88+
})
89+
print(str)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
foo = 44
2+
bar = hello
3+
nashorn -> hello
4+
-3,34,53,567
5+
-3,33,34,53,57,670
6+
he__o
7+
hELLo
+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/**
25+
* JDK-8157819: TypeError when a java.util.Comparator object is invoked as a function
26+
*
27+
* @test
28+
* @run
29+
*/
30+
31+
var compare = java.util.Comparator.naturalOrder()
32+
Assert.assertTrue(compare("nashorn", "ecmascript") > 0)
33+
Assert.assertTrue(compare("abc", "xyz") < 0)
34+
Assert.assertTrue(compare("hello", "hello") == 0)
35+
36+
var rcompare = java.util.Comparator.reverseOrder()
37+
Assert.assertTrue(rcompare("nashorn", "ecmascript") < 0)
38+
Assert.assertTrue(rcompare("abc", "xyz") > 0)
39+
Assert.assertTrue(rcompare("hello", "hello") == 0)
40+
41+
var arr = [ "nashorn", "JavaScript", "ECMAScript", "ecmascript", "js" ]
42+
Assert.assertEquals(arr.sort(compare).join(),
43+
"ECMAScript,JavaScript,ecmascript,js,nashorn")
44+
Assert.assertEquals(arr.sort(rcompare).join(),
45+
"nashorn,js,ecmascript,JavaScript,ECMAScript")
46+

0 commit comments

Comments
 (0)