--- a/nashorn/README Tue Jan 24 18:08:04 2017 +0530
+++ b/nashorn/README Wed Jan 25 09:49:02 2017 +0100
@@ -18,7 +18,7 @@
http://mercurial.selenic.com/wiki/ForestExtension
-and downlaoded using
+and downloaded using
hg clone https://bitbucket.org/gxti/hgforest
@@ -39,7 +39,7 @@
- How to build?
To build Nashorn, you need to install JDK 9. You may use the Nashorn
-forest build (recommended) or down load from java.net. You will need to
+forest build (recommended) or download from java.net. You will need to
set JAVA_HOME environmental variable to point to your JDK installation
directory.
--- a/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardedInvocation.java Tue Jan 24 18:08:04 2017 +0530
+++ b/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardedInvocation.java Wed Jan 25 09:49:02 2017 +0100
@@ -395,39 +395,45 @@
}
/**
- * Applies argument filters to both the invocation and the guard (if there
- * is one) with {@link MethodHandles#filterArguments(MethodHandle, int, MethodHandle...)}.
+ * Applies argument filters to both the invocation and the guard
+ * (if it exists and has at least {@code pos + 1} parameters) with
+ * {@link MethodHandles#filterArguments(MethodHandle, int, MethodHandle...)}.
* @param pos the position of the first argument being filtered
* @param filters the argument filters
* @return a filtered invocation
*/
public GuardedInvocation filterArguments(final int pos, final MethodHandle... filters) {
- return replaceMethods(MethodHandles.filterArguments(invocation, pos, filters), guard == null ? null :
- MethodHandles.filterArguments(guard, pos, filters));
+ return replaceMethods(MethodHandles.filterArguments(invocation, pos, filters),
+ guard == null || pos >= guard.type().parameterCount() ?
+ guard : MethodHandles.filterArguments(guard, pos, filters));
}
/**
* Makes an invocation that drops arguments in both the invocation and the
- * guard (if there is one) with {@link MethodHandles#dropArguments(MethodHandle, int, List)}.
+ * guard (if it exists and has at least {@code pos} parameters) with
+ * {@link MethodHandles#dropArguments(MethodHandle, int, List)}.
* @param pos the position of the first argument being dropped
* @param valueTypes the types of the values being dropped
* @return an invocation that drops arguments
*/
public GuardedInvocation dropArguments(final int pos, final List<Class<?>> valueTypes) {
- return replaceMethods(MethodHandles.dropArguments(invocation, pos, valueTypes), guard == null ? null :
- MethodHandles.dropArguments(guard, pos, valueTypes));
+ return replaceMethods(MethodHandles.dropArguments(invocation, pos, valueTypes),
+ guard == null || pos > guard.type().parameterCount() ?
+ guard : MethodHandles.dropArguments(guard, pos, valueTypes));
}
/**
* Makes an invocation that drops arguments in both the invocation and the
- * guard (if there is one) with {@link MethodHandles#dropArguments(MethodHandle, int, Class...)}.
+ * guard (if it exists and has at least {@code pos} parameters) with
+ * {@link MethodHandles#dropArguments(MethodHandle, int, Class...)}.
* @param pos the position of the first argument being dropped
* @param valueTypes the types of the values being dropped
* @return an invocation that drops arguments
*/
public GuardedInvocation dropArguments(final int pos, final Class<?>... valueTypes) {
- return replaceMethods(MethodHandles.dropArguments(invocation, pos, valueTypes), guard == null ? null :
- MethodHandles.dropArguments(guard, pos, valueTypes));
+ return replaceMethods(MethodHandles.dropArguments(invocation, pos, valueTypes),
+ guard == null || pos > guard.type().parameterCount() ?
+ guard : MethodHandles.dropArguments(guard, pos, valueTypes));
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/linker/NashornLinkerExporter.java Tue Jan 24 18:08:04 2017 +0530
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/linker/NashornLinkerExporter.java Wed Jan 25 09:49:02 2017 +0100
@@ -38,7 +38,7 @@
/**
* This linker exporter is a service provider that exports Nashorn Dynalink
- * linkers to external users. Other languague runtimes that use Dynalink
+ * linkers to external users. Other language runtimes that use Dynalink
* can use the linkers exported by this provider to support tight integration
* of Nashorn objects.
*/
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptFunction.java Tue Jan 24 18:08:04 2017 +0530
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptFunction.java Wed Jan 25 09:49:02 2017 +0100
@@ -735,7 +735,7 @@
/**
* Name getter - ECMA Function.name
*
- * @param self self refence
+ * @param self self reference
* @return the name, or undefined if none
*/
public static Object G$name(final Object self) {
@@ -1120,12 +1120,19 @@
assert appliedRequest != null; // Bootstrap.isCallable() returned true for args[1], so it must produce a linkage.
final Class<?> applyFnType = descType.parameterType(0);
- MethodHandle inv = appliedInvocation.getInvocation(); //method handle from apply invocation. the applied function invocation
+ // Invocation and guard handles from apply invocation.
+ MethodHandle inv = appliedInvocation.getInvocation();
+ MethodHandle guard = appliedInvocation.getGuard();
if (isApply && !isFailedApplyToCall) {
if (passesArgs) {
// Make sure that the passed argArray is converted to Object[] the same way NativeFunction.apply() would do it.
inv = MH.filterArguments(inv, 2, NativeFunction.TO_APPLY_ARGS);
+ // Some guards (non-strict functions with non-primitive this) have a this-object parameter, so we
+ // need to apply this transformations to them as well.
+ if (guard.type().parameterCount() > 2) {
+ guard = MH.filterArguments(guard, 2, NativeFunction.TO_APPLY_ARGS);
+ }
} else {
// If the original call site doesn't pass argArray, pass in an empty array
inv = MH.insertArguments(inv, 2, (Object) ScriptRuntime.EMPTY_ARRAY);
@@ -1144,12 +1151,25 @@
if (!passesThis) {
// If the original call site doesn't pass in a thisArg, pass in Global/undefined as needed
- inv = bindImplicitThis(appliedFn, inv);
+ inv = bindImplicitThis(appliedFnNeedsWrappedThis, inv);
+ // guard may have this-parameter that needs to be inserted
+ if (guard.type().parameterCount() > 1) {
+ guard = bindImplicitThis(appliedFnNeedsWrappedThis, guard);
+ }
} else if (appliedFnNeedsWrappedThis) {
// target function needs a wrapped this, so make sure we filter for that
inv = MH.filterArguments(inv, 1, WRAP_THIS);
+ // guard may have this-parameter that needs to be wrapped
+ if (guard.type().parameterCount() > 1) {
+ guard = MH.filterArguments(guard, 1, WRAP_THIS);
+ }
}
+
+ final MethodType guardType = guard.type(); // Needed for combining guards below
+
+ // We need to account for the dropped (apply|call) function argument.
inv = MH.dropArguments(inv, 0, applyFnType);
+ guard = MH.dropArguments(guard, 0, applyFnType);
/*
* Dropargs can only be non-()V in the case of isApply && !isFailedApplyToCall, which
@@ -1160,15 +1180,6 @@
inv = MH.dropArguments(inv, 4 + i, dropArgs.parameterType(i));
}
- MethodHandle guard = appliedInvocation.getGuard();
- // If the guard checks the value of "this" but we aren't passing thisArg, insert the default one
- if (!passesThis && guard.type().parameterCount() > 1) {
- guard = bindImplicitThis(appliedFn, guard);
- }
- final MethodType guardType = guard.type();
-
- // We need to account for the dropped (apply|call) function argument.
- guard = MH.dropArguments(guard, 0, descType.parameterType(0));
// Take the "isApplyFunction" guard, and bind it to this function.
MethodHandle applyFnGuard = MH.insertArguments(IS_APPLY_FUNCTION, 2, this); //TODO replace this with switchpoint
// Adapt the guard to receive all the arguments that the original guard does.
@@ -1244,9 +1255,9 @@
return ScriptObject.adaptHandleToVarArgCallSite(arrayConvertingGuard, descParamCount);
}
- private static MethodHandle bindImplicitThis(final Object fn, final MethodHandle mh) {
+ private static MethodHandle bindImplicitThis(final boolean needsWrappedThis, final MethodHandle mh) {
final MethodHandle bound;
- if (fn instanceof ScriptFunction && ((ScriptFunction) fn).needsWrappedThis()) {
+ if (needsWrappedThis) {
bound = MH.filterArguments(mh, 1, SCRIPTFUNCTION_GLOBALFILTER);
} else {
bound = mh;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8166186.js Wed Jan 25 09:49:02 2017 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/**
+ * 8166186: ClassCastException with arguments usage
+ *
+ * @test
+ * @run
+ */
+
+function F (arg) {
+ print("F called");
+ Function.prototype.call.apply(G, arguments);
+}
+
+function G (){
+ print("G called");
+ print(this);
+ if (C++ > 5) return;
+ F("argument " + C);
+}
+
+var C = 0;
+
+G();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8166186.js.EXPECTED Wed Jan 25 09:49:02 2017 +0100
@@ -0,0 +1,20 @@
+G called
+[object global]
+F called
+G called
+argument 1
+F called
+G called
+argument 2
+F called
+G called
+argument 3
+F called
+G called
+argument 4
+F called
+G called
+argument 5
+F called
+G called
+argument 6