8087136: regression: apply on $EXEC fails with ClassCastException

Reviewed-by: hannesw, lagergren
This commit is contained in:
Athijegannathan Sundararajan 2015-06-11 13:33:34 +05:30
parent 0f1bfba6c9
commit f3198a6632
3 changed files with 11 additions and 11 deletions

View file

@ -46,3 +46,5 @@ $EXEC("ls", "" /* no stdin */, ["-l", "-a"])
// Output of running external commands is returned from $EXEC: // Output of running external commands is returned from $EXEC:
print($EXEC("ls")) print($EXEC("ls"))
// apply on $EXEC
print($EXEC.apply(this, ["ls"]));

View file

@ -2580,18 +2580,15 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
final int parameterCount = methodType.parameterCount(); final int parameterCount = methodType.parameterCount();
final int callCount = callType.parameterCount(); final int callCount = callType.parameterCount();
final int pdiff = callCount - parameterCount + 1;
final boolean isCalleeVarArg = parameterCount > 0 && methodType.parameterType(parameterCount - 1).isArray(); final boolean isCalleeVarArg = parameterCount > 0 && methodType.parameterType(parameterCount - 1).isArray();
final boolean isCallerVarArg = callerVarArg != null ? callerVarArg : callCount > 0 && final boolean isCallerVarArg = callerVarArg != null ? callerVarArg : callCount > 0 &&
callType.parameterType(callCount - 1).isArray(); 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 if (isCalleeVarArg) {
// by the vararg collector. No vararg collector is required in that case, and no varargs are passed.
if (isCalleeVarArg && pdiff >= 0) {
return isCallerVarArg ? return isCallerVarArg ?
methodHandle : methodHandle :
MH.asCollector(methodHandle, Object[].class, pdiff); MH.asCollector(methodHandle, Object[].class, callCount - parameterCount + 1);
} }
if (isCallerVarArg) { if (isCallerVarArg) {

View file

@ -39,6 +39,7 @@ import java.io.StringReader;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import jdk.nashorn.internal.objects.NativeArray; import jdk.nashorn.internal.objects.NativeArray;
@ -55,7 +56,7 @@ public final class ScriptingFunctions {
public static final MethodHandle READFULLY = findOwnMH("readFully", Object.class, Object.class, Object.class); public static final MethodHandle READFULLY = findOwnMH("readFully", Object.class, Object.class, Object.class);
/** Handle to implementation of {@link ScriptingFunctions#exec} - Nashorn extension */ /** 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. */ /** EXEC name - special property used by $EXEC API. */
public static final String EXEC_NAME = "$EXEC"; public static final String EXEC_NAME = "$EXEC";
@ -127,9 +128,7 @@ public final class ScriptingFunctions {
* Nashorn extension: exec a string in a separate process. * Nashorn extension: exec a string in a separate process.
* *
* @param self self reference * @param self self reference
* @param string string to execute * @param args string to execute, input and additional arguments, to be appended to {@code string}. Additional arguments can be passed as
* @param input input
* @param argv 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 * 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. * varargs, each of which will be converted to a string.
* *
@ -138,10 +137,12 @@ public final class ScriptingFunctions {
* @throws IOException if any stream access fails * @throws IOException if any stream access fails
* @throws InterruptedException if execution is interrupted * @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. // Current global is need to fetch additional inputs and for additional results.
final ScriptObject global = Context.getGlobal(); 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. // Assemble command line, process additional arguments.
final List<String> cmdLine = tokenizeString(JSType.toString(string)); final List<String> cmdLine = tokenizeString(JSType.toString(string));
final Object[] additionalArgs = argv.length == 1 && argv[0] instanceof NativeArray ? final Object[] additionalArgs = argv.length == 1 && argv[0] instanceof NativeArray ?