8087136: regression: apply on $EXEC fails with ClassCastException
authorsundar
Thu, 11 Jun 2015 13:33:34 +0530
changeset 31100 4f7ba6a0bb37
parent 31099 c5dcfe771907
child 31101 b15ed6c5dedd
8087136: regression: apply on $EXEC fails with ClassCastException Reviewed-by: hannesw, lagergren
nashorn/samples/exec.js
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptingFunctions.java
--- a/nashorn/samples/exec.js	Tue Jun 09 09:27:02 2015 +0200
+++ b/nashorn/samples/exec.js	Thu Jun 11 13:33:34 2015 +0530
@@ -46,3 +46,5 @@
 // Output of running external commands is returned from $EXEC:
 print($EXEC("ls"))
 
+// apply on $EXEC
+print($EXEC.apply(this, ["ls"]));
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java	Tue Jun 09 09:27:02 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java	Thu Jun 11 13:33:34 2015 +0530
@@ -2580,18 +2580,15 @@
 
         final int parameterCount = methodType.parameterCount();
         final int callCount      = callType.parameterCount();
-        final int pdiff          = callCount - parameterCount + 1;
 
         final boolean isCalleeVarArg = parameterCount > 0 && methodType.parameterType(parameterCount - 1).isArray();
         final boolean isCallerVarArg = callerVarArg != null ? callerVarArg : callCount > 0 &&
                 callType.parameterType(callCount - 1).isArray();
 
-        // A value of pdiff < 0 means that there are additional normal arguments in the callee that must not be consumed
-        // by the vararg collector. No vararg collector is required in that case, and no varargs are passed.
-        if (isCalleeVarArg && pdiff >= 0) {
+        if (isCalleeVarArg) {
             return isCallerVarArg ?
                 methodHandle :
-                MH.asCollector(methodHandle, Object[].class, pdiff);
+                MH.asCollector(methodHandle, Object[].class, callCount - parameterCount + 1);
         }
 
         if (isCallerVarArg) {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptingFunctions.java	Tue Jun 09 09:27:02 2015 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptingFunctions.java	Thu Jun 11 13:33:34 2015 +0530
@@ -39,6 +39,7 @@
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 import jdk.nashorn.internal.objects.NativeArray;
@@ -55,7 +56,7 @@
     public static final MethodHandle READFULLY = findOwnMH("readFully",     Object.class, Object.class, Object.class);
 
     /** Handle to implementation of {@link ScriptingFunctions#exec} - Nashorn extension */
-    public static final MethodHandle EXEC = findOwnMH("exec",     Object.class, Object.class, Object.class, Object.class, Object[].class);
+    public static final MethodHandle EXEC = findOwnMH("exec",     Object.class, Object.class, Object[].class);
 
     /** EXEC name - special property used by $EXEC API. */
     public static final String EXEC_NAME = "$EXEC";
@@ -127,9 +128,7 @@
      * Nashorn extension: exec a string in a separate process.
      *
      * @param self   self reference
-     * @param string string to execute
-     * @param input  input
-     * @param argv   additional arguments, to be appended to {@code string}. Additional arguments can be passed as
+     * @param args   string to execute, input and additional arguments, to be appended to {@code string}. Additional arguments can be passed as
      *               either one JavaScript array, whose elements will be converted to strings; or as a sequence of
      *               varargs, each of which will be converted to a string.
      *
@@ -138,10 +137,12 @@
      * @throws IOException           if any stream access fails
      * @throws InterruptedException  if execution is interrupted
      */
-    public static Object exec(final Object self, final Object string, final Object input, final Object... argv) throws IOException, InterruptedException {
+    public static Object exec(final Object self, final Object... args) throws IOException, InterruptedException {
         // Current global is need to fetch additional inputs and for additional results.
         final ScriptObject global = Context.getGlobal();
-
+        final Object string = args.length > 0? args[0] : UNDEFINED;
+        final Object input = args.length > 1? args[1] : UNDEFINED;
+        final Object[] argv = (args.length > 2)? Arrays.copyOfRange(args, 2, args.length) : ScriptRuntime.EMPTY_ARRAY;
         // Assemble command line, process additional arguments.
         final List<String> cmdLine = tokenizeString(JSType.toString(string));
         final Object[] additionalArgs = argv.length == 1 && argv[0] instanceof NativeArray ?