src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java

changeset 101
f8221ce53c2e
parent 90
5a820fb11814
child 404
18d467e94150
     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 +}

mercurial