nashorn/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java
changeset 16245 6a1c6c8bc113
parent 16234 86cb162cec6c
child 18841 9bbc4b8832b2
--- a/nashorn/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java	Mon Feb 18 10:36:18 2013 +0100
+++ b/nashorn/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java	Mon Feb 18 16:00:15 2013 +0100
@@ -92,7 +92,6 @@
 import jdk.internal.dynalink.linker.LinkerServices;
 import jdk.internal.dynalink.support.TypeUtilities;
 
-
 /**
  * Represents an overloaded method.
  *
@@ -204,14 +203,16 @@
                 final MethodHandle mh = invokables.iterator().next();
                 return new SimpleDynamicMethod(mh).getInvocation(callSiteType, linkerServices);
             }
+            default: {
+                // We have more than one candidate. We have no choice but to link to a method that resolves overloads on
+                // every invocation (alternatively, we could opportunistically link the one method that resolves for the
+                // current arguments, but we'd need to install a fairly complex guard for that and when it'd fail, we'd
+                // go back all the way to candidate selection.
+                // TODO: cache per call site type
+                return new OverloadedMethod(invokables, this, callSiteType, linkerServices).getInvoker();
+            }
         }
 
-        // We have more than one candidate. We have no choice but to link to a method that resolves overloads on every
-        // invocation (alternatively, we could opportunistically link the one method that resolves for the current
-        // arguments, but we'd need to install a fairly complex guard for that and when it'd fail, we'd go back all the
-        // way to candidate selection.
-        // TODO: cache per call site type
-        return new OverloadedMethod(invokables, this, callSiteType, linkerServices).getInvoker();
     }
 
     @Override
@@ -248,6 +249,8 @@
         final boolean varArgs = m.isVarargsCollector();
         final int fixedArgLen = methodType.parameterCount() - (varArgs ? 1 : 0);
         final int callSiteArgLen = callSiteType.parameterCount();
+
+        // Arity checks
         if(varArgs) {
             if(callSiteArgLen < fixedArgLen) {
                 return false;
@@ -255,32 +258,36 @@
         } else if(callSiteArgLen != fixedArgLen) {
             return false;
         }
-        // Starting from 1, as receiver type doesn't participate
+
+        // Fixed arguments type checks, starting from 1, as receiver type doesn't participate
         for(int i = 1; i < fixedArgLen; ++i) {
             if(!isApplicableDynamically(linkerServices, callSiteType.parameterType(i), methodType.parameterType(i))) {
                 return false;
             }
         }
-        if(varArgs) {
-            final Class<?> varArgArrayType = methodType.parameterType(fixedArgLen);
-            final Class<?> varArgType = varArgArrayType.getComponentType();
-            if(fixedArgLen == callSiteArgLen - 1) {
-                final Class<?> callSiteArgType = callSiteType.parameterType(fixedArgLen);
-                // Exactly one vararg; check both exact matching and component
-                // matching.
-                return isApplicableDynamically(linkerServices, callSiteArgType, varArgArrayType)
-                        || isApplicableDynamically(linkerServices, callSiteArgType, varArgType);
-            } else {
-                for(int i = fixedArgLen; i < callSiteArgLen; ++i) {
-                    if(!isApplicableDynamically(linkerServices, callSiteType.parameterType(i), varArgType)) {
-                        return false;
-                    }
-                }
-                return true;
-            }
-        } else {
+        if(!varArgs) {
+            // Not vararg; both arity and types matched.
             return true;
         }
+
+        final Class<?> varArgArrayType = methodType.parameterType(fixedArgLen);
+        final Class<?> varArgType = varArgArrayType.getComponentType();
+
+        if(fixedArgLen == callSiteArgLen - 1) {
+            // Exactly one vararg; check both array type matching and array component type matching.
+            final Class<?> callSiteArgType = callSiteType.parameterType(fixedArgLen);
+            return isApplicableDynamically(linkerServices, callSiteArgType, varArgArrayType)
+                    || isApplicableDynamically(linkerServices, callSiteArgType, varArgType);
+        }
+
+        // Either zero, or more than one vararg; check if all actual vararg types match the vararg array component type.
+        for(int i = fixedArgLen; i < callSiteArgLen; ++i) {
+            if(!isApplicableDynamically(linkerServices, callSiteType.parameterType(i), varArgType)) {
+                return false;
+            }
+        }
+
+        return true;
     }
 
     private static boolean isApplicableDynamically(LinkerServices linkerServices, Class<?> callSiteType,
@@ -298,7 +305,7 @@
      *
      * @param method the method to add.
      */
-    public void addMethod(SimpleDynamicMethod method) {
+    void addMethod(SimpleDynamicMethod method) {
         addMethod(method.getTarget());
     }
 
@@ -310,4 +317,4 @@
     public void addMethod(MethodHandle method) {
         methods.add(method);
     }
-}
\ No newline at end of file
+}