1.1 --- a/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java Mon Feb 18 10:36:18 2013 +0100 1.2 +++ b/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java Mon Feb 18 16:00:15 2013 +0100 1.3 @@ -92,7 +92,6 @@ 1.4 import jdk.internal.dynalink.linker.LinkerServices; 1.5 import jdk.internal.dynalink.support.TypeUtilities; 1.6 1.7 - 1.8 /** 1.9 * Represents an overloaded method. 1.10 * 1.11 @@ -204,14 +203,16 @@ 1.12 final MethodHandle mh = invokables.iterator().next(); 1.13 return new SimpleDynamicMethod(mh).getInvocation(callSiteType, linkerServices); 1.14 } 1.15 + default: { 1.16 + // We have more than one candidate. We have no choice but to link to a method that resolves overloads on 1.17 + // every invocation (alternatively, we could opportunistically link the one method that resolves for the 1.18 + // current arguments, but we'd need to install a fairly complex guard for that and when it'd fail, we'd 1.19 + // go back all the way to candidate selection. 1.20 + // TODO: cache per call site type 1.21 + return new OverloadedMethod(invokables, this, callSiteType, linkerServices).getInvoker(); 1.22 + } 1.23 } 1.24 1.25 - // We have more than one candidate. We have no choice but to link to a method that resolves overloads on every 1.26 - // invocation (alternatively, we could opportunistically link the one method that resolves for the current 1.27 - // arguments, but we'd need to install a fairly complex guard for that and when it'd fail, we'd go back all the 1.28 - // way to candidate selection. 1.29 - // TODO: cache per call site type 1.30 - return new OverloadedMethod(invokables, this, callSiteType, linkerServices).getInvoker(); 1.31 } 1.32 1.33 @Override 1.34 @@ -248,6 +249,8 @@ 1.35 final boolean varArgs = m.isVarargsCollector(); 1.36 final int fixedArgLen = methodType.parameterCount() - (varArgs ? 1 : 0); 1.37 final int callSiteArgLen = callSiteType.parameterCount(); 1.38 + 1.39 + // Arity checks 1.40 if(varArgs) { 1.41 if(callSiteArgLen < fixedArgLen) { 1.42 return false; 1.43 @@ -255,32 +258,36 @@ 1.44 } else if(callSiteArgLen != fixedArgLen) { 1.45 return false; 1.46 } 1.47 - // Starting from 1, as receiver type doesn't participate 1.48 + 1.49 + // Fixed arguments type checks, starting from 1, as receiver type doesn't participate 1.50 for(int i = 1; i < fixedArgLen; ++i) { 1.51 if(!isApplicableDynamically(linkerServices, callSiteType.parameterType(i), methodType.parameterType(i))) { 1.52 return false; 1.53 } 1.54 } 1.55 - if(varArgs) { 1.56 - final Class<?> varArgArrayType = methodType.parameterType(fixedArgLen); 1.57 - final Class<?> varArgType = varArgArrayType.getComponentType(); 1.58 - if(fixedArgLen == callSiteArgLen - 1) { 1.59 - final Class<?> callSiteArgType = callSiteType.parameterType(fixedArgLen); 1.60 - // Exactly one vararg; check both exact matching and component 1.61 - // matching. 1.62 - return isApplicableDynamically(linkerServices, callSiteArgType, varArgArrayType) 1.63 - || isApplicableDynamically(linkerServices, callSiteArgType, varArgType); 1.64 - } else { 1.65 - for(int i = fixedArgLen; i < callSiteArgLen; ++i) { 1.66 - if(!isApplicableDynamically(linkerServices, callSiteType.parameterType(i), varArgType)) { 1.67 - return false; 1.68 - } 1.69 - } 1.70 - return true; 1.71 - } 1.72 - } else { 1.73 + if(!varArgs) { 1.74 + // Not vararg; both arity and types matched. 1.75 return true; 1.76 } 1.77 + 1.78 + final Class<?> varArgArrayType = methodType.parameterType(fixedArgLen); 1.79 + final Class<?> varArgType = varArgArrayType.getComponentType(); 1.80 + 1.81 + if(fixedArgLen == callSiteArgLen - 1) { 1.82 + // Exactly one vararg; check both array type matching and array component type matching. 1.83 + final Class<?> callSiteArgType = callSiteType.parameterType(fixedArgLen); 1.84 + return isApplicableDynamically(linkerServices, callSiteArgType, varArgArrayType) 1.85 + || isApplicableDynamically(linkerServices, callSiteArgType, varArgType); 1.86 + } 1.87 + 1.88 + // Either zero, or more than one vararg; check if all actual vararg types match the vararg array component type. 1.89 + for(int i = fixedArgLen; i < callSiteArgLen; ++i) { 1.90 + if(!isApplicableDynamically(linkerServices, callSiteType.parameterType(i), varArgType)) { 1.91 + return false; 1.92 + } 1.93 + } 1.94 + 1.95 + return true; 1.96 } 1.97 1.98 private static boolean isApplicableDynamically(LinkerServices linkerServices, Class<?> callSiteType, 1.99 @@ -298,7 +305,7 @@ 1.100 * 1.101 * @param method the method to add. 1.102 */ 1.103 - public void addMethod(SimpleDynamicMethod method) { 1.104 + void addMethod(SimpleDynamicMethod method) { 1.105 addMethod(method.getTarget()); 1.106 } 1.107 1.108 @@ -310,4 +317,4 @@ 1.109 public void addMethod(MethodHandle method) { 1.110 methods.add(method); 1.111 } 1.112 -} 1.113 \ No newline at end of file 1.114 +}