changeset 1871:6f5bf136f6c9

Merge
author lana
date Thu, 26 Jan 2017 21:20:32 +0000
parents 336a75b38fd0 8e7ef537aa54
children f9bb37a817b3
files
diffstat 11 files changed, 223 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/README	Thu Jan 26 19:22:40 2017 +0000
+++ b/README	Thu Jan 26 21:20:32 2017 +0000
@@ -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/make/build.xml	Thu Jan 26 19:22:40 2017 +0000
+++ b/make/build.xml	Thu Jan 26 21:20:32 2017 +0000
@@ -394,6 +394,18 @@
 
   </target>
 
+  <target name="generate-security-config" depends="generate-policy-file, generate-security-properties-file"/>
+
+  <target name="generate-security-properties-file" depends="prepare">
+    <echo file="${build.dir}/nashorn.security.properties">
+
+package.access=sun.misc.,\
+    sun.reflect.,\
+    jdk.nashorn.internal.
+
+    </echo>
+  </target>
+
   <target name="generate-policy-file" depends="prepare">
     <echo file="${build.dir}/nashorn.policy">
 
@@ -600,7 +612,7 @@
 
   <target name="test" depends="prepare, javadoc, test-pessimistic, test-optimistic"/>
 
-  <target name="test-optimistic" depends="jar, -test-classes-all,-test-classes-single, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
+  <target name="test-optimistic" depends="jar, -test-classes-all,-test-classes-single, check-testng, check-external-tests, compile-test, generate-security-config" if="testng.available">
     <echo message="Running test suite in OPTIMISTIC mode..."/>
     <antcall target="-test-nosecurity" inheritRefs="true">
       <param name="optimistic" value="true"/>
@@ -612,7 +624,7 @@
     </antcall>
   </target>
 
-  <target name="test-pessimistic" depends="jar, -test-classes-all,-test-classes-single, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
+  <target name="test-pessimistic" depends="jar, -test-classes-all,-test-classes-single, check-testng, check-external-tests, compile-test, generate-security-config" if="testng.available">
     <echo message="Running test suite in PESSIMISTIC mode..."/>
     <antcall target="-test-nosecurity" inheritRefs="true">
       <param name="optimistic" value="false"/>
@@ -655,7 +667,7 @@
     </testng>
   </target>
 
-  <target name="testmarkdown" depends="jar, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
+  <target name="testmarkdown" depends="jar, check-testng, check-external-tests, compile-test, generate-security-config" if="testng.available">
     <fileset id="test.classes" dir="${build.test.classes.dir}">
        <include name="**/framework/*Test.class"/>
     </fileset>
@@ -673,7 +685,7 @@
     </testng>
   </target>
 
-  <target name="test262" depends="jar, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
+  <target name="test262" depends="jar, check-testng, check-external-tests, compile-test, generate-security-config" if="testng.available">
     <fileset id="test.classes" dir="${build.test.classes.dir}">
        <include name="**/framework/*Test.class"/>
     </fileset>
@@ -696,7 +708,7 @@
 
   <target name="test262parallel" depends="test262-parallel"/>
 
-  <target name="test262-parallel" depends="jar, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
+  <target name="test262-parallel" depends="jar, check-testng, check-external-tests, compile-test, generate-security-config" if="testng.available">
     <!-- use just build.test.classes.dir to avoid referring to TestNG -->
     <java classname="${parallel.test.runner}" dir="${basedir}" fork="true" failonerror="true">
       <jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs} -Dbuild.dir=${build.dir}"/>
@@ -714,7 +726,7 @@
 
   <target name="testparallel" depends="test-parallel"/>
 
-  <target name="test-parallel" depends="jar, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
+  <target name="test-parallel" depends="jar, check-testng, check-external-tests, compile-test, generate-security-config" if="testng.available">
       <!-- use just build.test.classes.dir to avoid referring to TestNG -->
       <java classname="${parallel.test.runner}" dir="${basedir}"
         failonerror="true"
--- a/make/project.properties	Thu Jan 26 19:22:40 2017 +0000
+++ b/make/project.properties	Thu Jan 26 21:20:32 2017 +0000
@@ -408,7 +408,7 @@
 run.test.jvmargs.octane.main=${run.test.jvmargs.common} -XX:TypeProfileLevel=222
 
 # Security manager args - make sure that we run with the nashorn.policy that the build creates
-run.test.jvmsecurityargs=-Xverify:all -Djava.security.manager -Djava.security.policy=${build.dir}/nashorn.policy
+run.test.jvmsecurityargs=-Xverify:all -Djava.security.manager -Djava.security.policy=${build.dir}/nashorn.policy -Djava.security.properties=${build.dir}/nashorn.security.properties
 
 # VM options for script tests with @fork option
 test-sys-prop.test.fork.jvm.options=${run.test.jvmargs.main} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs} -cp ${run.test.classpath}
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardedInvocation.java	Thu Jan 26 19:22:40 2017 +0000
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardedInvocation.java	Thu Jan 26 21:20:32 2017 +0000
@@ -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/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/linker/NashornLinkerExporter.java	Thu Jan 26 19:22:40 2017 +0000
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/linker/NashornLinkerExporter.java	Thu Jan 26 21:20:32 2017 +0000
@@ -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/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptFunction.java	Thu Jan 26 19:22:40 2017 +0000
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptFunction.java	Thu Jan 26 21:20:32 2017 +0000
@@ -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;
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java	Thu Jan 26 19:22:40 2017 +0000
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java	Thu Jan 26 21:20:32 2017 +0000
@@ -147,9 +147,8 @@
                         new NashornBeansLinkerServices(linkerServices));
 
                 // Bind to the method, drop the original "this" and use original "callee" as this:
-                final MethodHandle inv = linkerServices.filterInternalObjects(gi
-                        .getInvocation()  // (method, this, args...)
-                        .bindTo(method)); // (this, args...)
+                final MethodHandle inv = gi.getInvocation()  // (method, this, args...)
+                                           .bindTo(method);  // (this, args...)
                 final MethodHandle calleeToThis = MH.dropArguments(inv, 1, callType.parameterType(1)); // (callee->this, <drop>, args...)
                 return gi.replaceMethods(calleeToThis, gi.getGuard());
             }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8166186.js	Thu Jan 26 21:20:32 2017 +0000
@@ -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/test/script/basic/JDK-8166186.js.EXPECTED	Thu Jan 26 21:20:32 2017 +0000
@@ -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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8172006.js	Thu Jan 26 21:20:32 2017 +0000
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+/**
+ * JDK-8172006: Nashorn JavaScript engine fails to call @FunctionalInterface with a java.util.List argument
+ *
+ * @test
+ * @run
+ */
+
+var f = Java.type("jdk.nashorn.test.models.FunctionalInterfaceProvider").getImpl();
+
+var s = "a";
+s += "b";
+var o = { p: 10 };
+var a = [1, 2, 3];
+
+f([ f([]), f([]), f([]), f([]), f([]), f([]), f([]), f([]) ]);
+f([ f([]), f([ f([]), f([f([]), f([]), f([]) ]), f([])]), f([]) ]);
+f([ f([s]), f([o]), f([a]), f([s + "c"]), f([o]), f([a]) ]);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/src/jdk/nashorn/test/models/FunctionalInterfaceProvider.java	Thu Jan 26 21:20:32 2017 +0000
@@ -0,0 +1,53 @@
+/*
+ * 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.  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;
+
+import jdk.nashorn.api.scripting.ScriptObjectMirror;
+import org.testng.Assert;
+
+import java.util.List;
+
+public class FunctionalInterfaceProvider {
+
+    private final static Object RETURN_TOKEN = new Object();
+
+    public static Functional getImpl() {
+        return (l) -> {
+            // Make sure parameters are properly exported
+            for (final Object o : l) {
+                Assert.assertTrue(o == RETURN_TOKEN
+                        || o instanceof ScriptObjectMirror
+                        || o instanceof String);
+            }
+            return RETURN_TOKEN;
+        };
+    }
+
+    @FunctionalInterface
+    public interface Functional {
+        Object method(List<Object> args);
+    }
+
+}