nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java
changeset 18868 f5359cad148c
parent 18614 addca7a10167
child 19456 8cc345d620c8
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java	Thu Jul 11 18:33:33 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java	Thu Jul 11 22:58:37 2013 +0530
@@ -71,6 +71,8 @@
 
     private static final MethodHandle IS_NONSTRICT_FUNCTION = findOwnMH("isNonStrictFunction", boolean.class, Object.class, Object.class, ScriptFunctionData.class);
 
+    private static final MethodHandle ADD_ZEROTH_ELEMENT = findOwnMH("addZerothElement", Object[].class, Object[].class, Object.class);
+
     /** The parent scope. */
     private final ScriptObject scope;
 
@@ -546,7 +548,21 @@
     }
 
     private static MethodHandle bindToNameIfNeeded(final MethodHandle methodHandle, final String bindName) {
-        return bindName == null ? methodHandle : MH.insertArguments(methodHandle, 1, bindName);
+        if (bindName == null) {
+            return methodHandle;
+        } else {
+            // if it is vararg method, we need to extend argument array with
+            // a new zeroth element that is set to bindName value.
+            final MethodType methodType = methodHandle.type();
+            final int parameterCount = methodType.parameterCount();
+            final boolean isVarArg = parameterCount > 0 && methodType.parameterType(parameterCount - 1).isArray();
+
+            if (isVarArg) {
+                return MH.filterArguments(methodHandle, 1, MH.insertArguments(ADD_ZEROTH_ELEMENT, 1, bindName));
+            } else {
+                return MH.insertArguments(methodHandle, 1, bindName);
+            }
+        }
     }
 
     /**
@@ -586,6 +602,16 @@
         return self instanceof ScriptFunction && ((ScriptFunction)self).data == data && arg instanceof ScriptObject;
     }
 
+    @SuppressWarnings("unused")
+    private static Object[] addZerothElement(final Object[] args, final Object value) {
+        // extends input array with by adding new zeroth element
+        final Object[] src = (args == null)? ScriptRuntime.EMPTY_ARRAY : args;
+        final Object[] result = new Object[src.length + 1];
+        System.arraycopy(src, 0, result, 1, src.length);
+        result[0] = value;
+        return result;
+    }
+
     private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
         final Class<?>   own = ScriptFunction.class;
         final MethodType mt  = MH.type(rtype, types);