Java Code Examples for jdk.internal.dynalink.CallSiteDescriptor#getLookup()
The following examples show how to use
jdk.internal.dynalink.CallSiteDescriptor#getLookup() .
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: OverloadedDynamicMethod.java From TencentKona-8 with GNU General Public License v2.0 | 4 votes |
@Override public MethodHandle getInvocation(final CallSiteDescriptor callSiteDescriptor, final LinkerServices linkerServices) { final MethodType callSiteType = callSiteDescriptor.getMethodType(); // First, find all methods applicable to the call site by subtyping (JLS 15.12.2.2) final ApplicableOverloadedMethods subtypingApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_SUBTYPING); // Next, find all methods applicable by method invocation conversion to the call site (JLS 15.12.2.3). final ApplicableOverloadedMethods methodInvocationApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_METHOD_INVOCATION_CONVERSION); // Finally, find all methods applicable by variable arity invocation. (JLS 15.12.2.4). final ApplicableOverloadedMethods variableArityApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_VARIABLE_ARITY); // Find the methods that are maximally specific based on the call site signature List<SingleDynamicMethod> maximallySpecifics = subtypingApplicables.findMaximallySpecificMethods(); if(maximallySpecifics.isEmpty()) { maximallySpecifics = methodInvocationApplicables.findMaximallySpecificMethods(); if(maximallySpecifics.isEmpty()) { maximallySpecifics = variableArityApplicables.findMaximallySpecificMethods(); } } // Now, get a list of the rest of the methods; those that are *not* applicable to the call site signature based // on JLS rules. As paradoxical as that might sound, we have to consider these for dynamic invocation, as they // might match more concrete types passed in invocations. That's why we provisionally call them "invokables". // This is typical for very generic signatures at call sites. Typical example: call site specifies // (Object, Object), and we have a method whose parameter types are (String, int). None of the JLS applicability // rules will trigger, but we must consider the method, as it can be the right match for a concrete invocation. @SuppressWarnings({ "unchecked", "rawtypes" }) final List<SingleDynamicMethod> invokables = (List)methods.clone(); invokables.removeAll(subtypingApplicables.getMethods()); invokables.removeAll(methodInvocationApplicables.getMethods()); invokables.removeAll(variableArityApplicables.getMethods()); for(final Iterator<SingleDynamicMethod> it = invokables.iterator(); it.hasNext();) { final SingleDynamicMethod m = it.next(); if(!isApplicableDynamically(linkerServices, callSiteType, m)) { it.remove(); } } // If no additional methods can apply at invocation time, and there's more than one maximally specific method // based on call site signature, that is a link-time ambiguity. In a static scenario, javac would report an // ambiguity error. if(invokables.isEmpty() && maximallySpecifics.size() > 1) { throw new BootstrapMethodError("Can't choose among " + maximallySpecifics + " for argument types " + callSiteType); } // Merge them all. invokables.addAll(maximallySpecifics); switch(invokables.size()) { case 0: { // No overloads can ever match the call site type return null; } case 1: { // Very lucky, we ended up with a single candidate method handle based on the call site signature; we // can link it very simply by delegating to the SingleDynamicMethod. return invokables.iterator().next().getInvocation(callSiteDescriptor, 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. Note that we're resolving any potential caller sensitive // methods here to their handles, as the OverloadedMethod instance is specific to a call site, so it // has an already determined Lookup. final List<MethodHandle> methodHandles = new ArrayList<>(invokables.size()); final MethodHandles.Lookup lookup = callSiteDescriptor.getLookup(); for(final SingleDynamicMethod method: invokables) { methodHandles.add(method.getTarget(lookup)); } return new OverloadedMethod(methodHandles, this, callSiteType, linkerServices).getInvoker(); } } }
Example 2
Source File: OverloadedDynamicMethod.java From jdk8u60 with GNU General Public License v2.0 | 4 votes |
@Override public MethodHandle getInvocation(final CallSiteDescriptor callSiteDescriptor, final LinkerServices linkerServices) { final MethodType callSiteType = callSiteDescriptor.getMethodType(); // First, find all methods applicable to the call site by subtyping (JLS 15.12.2.2) final ApplicableOverloadedMethods subtypingApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_SUBTYPING); // Next, find all methods applicable by method invocation conversion to the call site (JLS 15.12.2.3). final ApplicableOverloadedMethods methodInvocationApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_METHOD_INVOCATION_CONVERSION); // Finally, find all methods applicable by variable arity invocation. (JLS 15.12.2.4). final ApplicableOverloadedMethods variableArityApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_VARIABLE_ARITY); // Find the methods that are maximally specific based on the call site signature List<SingleDynamicMethod> maximallySpecifics = subtypingApplicables.findMaximallySpecificMethods(); if(maximallySpecifics.isEmpty()) { maximallySpecifics = methodInvocationApplicables.findMaximallySpecificMethods(); if(maximallySpecifics.isEmpty()) { maximallySpecifics = variableArityApplicables.findMaximallySpecificMethods(); } } // Now, get a list of the rest of the methods; those that are *not* applicable to the call site signature based // on JLS rules. As paradoxical as that might sound, we have to consider these for dynamic invocation, as they // might match more concrete types passed in invocations. That's why we provisionally call them "invokables". // This is typical for very generic signatures at call sites. Typical example: call site specifies // (Object, Object), and we have a method whose parameter types are (String, int). None of the JLS applicability // rules will trigger, but we must consider the method, as it can be the right match for a concrete invocation. @SuppressWarnings({ "unchecked", "rawtypes" }) final List<SingleDynamicMethod> invokables = (List)methods.clone(); invokables.removeAll(subtypingApplicables.getMethods()); invokables.removeAll(methodInvocationApplicables.getMethods()); invokables.removeAll(variableArityApplicables.getMethods()); for(final Iterator<SingleDynamicMethod> it = invokables.iterator(); it.hasNext();) { final SingleDynamicMethod m = it.next(); if(!isApplicableDynamically(linkerServices, callSiteType, m)) { it.remove(); } } // If no additional methods can apply at invocation time, and there's more than one maximally specific method // based on call site signature, that is a link-time ambiguity. In a static scenario, javac would report an // ambiguity error. if(invokables.isEmpty() && maximallySpecifics.size() > 1) { throw new BootstrapMethodError("Can't choose among " + maximallySpecifics + " for argument types " + callSiteType); } // Merge them all. invokables.addAll(maximallySpecifics); switch(invokables.size()) { case 0: { // No overloads can ever match the call site type return null; } case 1: { // Very lucky, we ended up with a single candidate method handle based on the call site signature; we // can link it very simply by delegating to the SingleDynamicMethod. return invokables.iterator().next().getInvocation(callSiteDescriptor, 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. Note that we're resolving any potential caller sensitive // methods here to their handles, as the OverloadedMethod instance is specific to a call site, so it // has an already determined Lookup. final List<MethodHandle> methodHandles = new ArrayList<>(invokables.size()); final MethodHandles.Lookup lookup = callSiteDescriptor.getLookup(); for(final SingleDynamicMethod method: invokables) { methodHandles.add(method.getTarget(lookup)); } return new OverloadedMethod(methodHandles, this, callSiteType, linkerServices).getInvoker(); } } }
Example 3
Source File: OverloadedDynamicMethod.java From openjdk-jdk8u with GNU General Public License v2.0 | 4 votes |
@Override public MethodHandle getInvocation(final CallSiteDescriptor callSiteDescriptor, final LinkerServices linkerServices) { final MethodType callSiteType = callSiteDescriptor.getMethodType(); // First, find all methods applicable to the call site by subtyping (JLS 15.12.2.2) final ApplicableOverloadedMethods subtypingApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_SUBTYPING); // Next, find all methods applicable by method invocation conversion to the call site (JLS 15.12.2.3). final ApplicableOverloadedMethods methodInvocationApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_METHOD_INVOCATION_CONVERSION); // Finally, find all methods applicable by variable arity invocation. (JLS 15.12.2.4). final ApplicableOverloadedMethods variableArityApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_VARIABLE_ARITY); // Find the methods that are maximally specific based on the call site signature List<SingleDynamicMethod> maximallySpecifics = subtypingApplicables.findMaximallySpecificMethods(); if(maximallySpecifics.isEmpty()) { maximallySpecifics = methodInvocationApplicables.findMaximallySpecificMethods(); if(maximallySpecifics.isEmpty()) { maximallySpecifics = variableArityApplicables.findMaximallySpecificMethods(); } } // Now, get a list of the rest of the methods; those that are *not* applicable to the call site signature based // on JLS rules. As paradoxical as that might sound, we have to consider these for dynamic invocation, as they // might match more concrete types passed in invocations. That's why we provisionally call them "invokables". // This is typical for very generic signatures at call sites. Typical example: call site specifies // (Object, Object), and we have a method whose parameter types are (String, int). None of the JLS applicability // rules will trigger, but we must consider the method, as it can be the right match for a concrete invocation. @SuppressWarnings({ "unchecked", "rawtypes" }) final List<SingleDynamicMethod> invokables = (List)methods.clone(); invokables.removeAll(subtypingApplicables.getMethods()); invokables.removeAll(methodInvocationApplicables.getMethods()); invokables.removeAll(variableArityApplicables.getMethods()); for(final Iterator<SingleDynamicMethod> it = invokables.iterator(); it.hasNext();) { final SingleDynamicMethod m = it.next(); if(!isApplicableDynamically(linkerServices, callSiteType, m)) { it.remove(); } } // If no additional methods can apply at invocation time, and there's more than one maximally specific method // based on call site signature, that is a link-time ambiguity. In a static scenario, javac would report an // ambiguity error. if(invokables.isEmpty() && maximallySpecifics.size() > 1) { throw new BootstrapMethodError("Can't choose among " + maximallySpecifics + " for argument types " + callSiteType); } // Merge them all. invokables.addAll(maximallySpecifics); switch(invokables.size()) { case 0: { // No overloads can ever match the call site type return null; } case 1: { // Very lucky, we ended up with a single candidate method handle based on the call site signature; we // can link it very simply by delegating to the SingleDynamicMethod. return invokables.iterator().next().getInvocation(callSiteDescriptor, 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. Note that we're resolving any potential caller sensitive // methods here to their handles, as the OverloadedMethod instance is specific to a call site, so it // has an already determined Lookup. final List<MethodHandle> methodHandles = new ArrayList<>(invokables.size()); final MethodHandles.Lookup lookup = callSiteDescriptor.getLookup(); for(final SingleDynamicMethod method: invokables) { methodHandles.add(method.getTarget(lookup)); } return new OverloadedMethod(methodHandles, this, callSiteType, linkerServices).getInvoker(); } } }
Example 4
Source File: OverloadedDynamicMethod.java From openjdk-jdk8u-backup with GNU General Public License v2.0 | 4 votes |
@Override public MethodHandle getInvocation(final CallSiteDescriptor callSiteDescriptor, final LinkerServices linkerServices) { final MethodType callSiteType = callSiteDescriptor.getMethodType(); // First, find all methods applicable to the call site by subtyping (JLS 15.12.2.2) final ApplicableOverloadedMethods subtypingApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_SUBTYPING); // Next, find all methods applicable by method invocation conversion to the call site (JLS 15.12.2.3). final ApplicableOverloadedMethods methodInvocationApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_METHOD_INVOCATION_CONVERSION); // Finally, find all methods applicable by variable arity invocation. (JLS 15.12.2.4). final ApplicableOverloadedMethods variableArityApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_VARIABLE_ARITY); // Find the methods that are maximally specific based on the call site signature List<SingleDynamicMethod> maximallySpecifics = subtypingApplicables.findMaximallySpecificMethods(); if(maximallySpecifics.isEmpty()) { maximallySpecifics = methodInvocationApplicables.findMaximallySpecificMethods(); if(maximallySpecifics.isEmpty()) { maximallySpecifics = variableArityApplicables.findMaximallySpecificMethods(); } } // Now, get a list of the rest of the methods; those that are *not* applicable to the call site signature based // on JLS rules. As paradoxical as that might sound, we have to consider these for dynamic invocation, as they // might match more concrete types passed in invocations. That's why we provisionally call them "invokables". // This is typical for very generic signatures at call sites. Typical example: call site specifies // (Object, Object), and we have a method whose parameter types are (String, int). None of the JLS applicability // rules will trigger, but we must consider the method, as it can be the right match for a concrete invocation. @SuppressWarnings({ "unchecked", "rawtypes" }) final List<SingleDynamicMethod> invokables = (List)methods.clone(); invokables.removeAll(subtypingApplicables.getMethods()); invokables.removeAll(methodInvocationApplicables.getMethods()); invokables.removeAll(variableArityApplicables.getMethods()); for(final Iterator<SingleDynamicMethod> it = invokables.iterator(); it.hasNext();) { final SingleDynamicMethod m = it.next(); if(!isApplicableDynamically(linkerServices, callSiteType, m)) { it.remove(); } } // If no additional methods can apply at invocation time, and there's more than one maximally specific method // based on call site signature, that is a link-time ambiguity. In a static scenario, javac would report an // ambiguity error. if(invokables.isEmpty() && maximallySpecifics.size() > 1) { throw new BootstrapMethodError("Can't choose among " + maximallySpecifics + " for argument types " + callSiteType); } // Merge them all. invokables.addAll(maximallySpecifics); switch(invokables.size()) { case 0: { // No overloads can ever match the call site type return null; } case 1: { // Very lucky, we ended up with a single candidate method handle based on the call site signature; we // can link it very simply by delegating to the SingleDynamicMethod. return invokables.iterator().next().getInvocation(callSiteDescriptor, 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. Note that we're resolving any potential caller sensitive // methods here to their handles, as the OverloadedMethod instance is specific to a call site, so it // has an already determined Lookup. final List<MethodHandle> methodHandles = new ArrayList<>(invokables.size()); final MethodHandles.Lookup lookup = callSiteDescriptor.getLookup(); for(final SingleDynamicMethod method: invokables) { methodHandles.add(method.getTarget(lookup)); } return new OverloadedMethod(methodHandles, this, callSiteType, linkerServices).getInvoker(); } } }
Example 5
Source File: OverloadedDynamicMethod.java From hottub with GNU General Public License v2.0 | 4 votes |
@Override public MethodHandle getInvocation(final CallSiteDescriptor callSiteDescriptor, final LinkerServices linkerServices) { final MethodType callSiteType = callSiteDescriptor.getMethodType(); // First, find all methods applicable to the call site by subtyping (JLS 15.12.2.2) final ApplicableOverloadedMethods subtypingApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_SUBTYPING); // Next, find all methods applicable by method invocation conversion to the call site (JLS 15.12.2.3). final ApplicableOverloadedMethods methodInvocationApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_METHOD_INVOCATION_CONVERSION); // Finally, find all methods applicable by variable arity invocation. (JLS 15.12.2.4). final ApplicableOverloadedMethods variableArityApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_VARIABLE_ARITY); // Find the methods that are maximally specific based on the call site signature List<SingleDynamicMethod> maximallySpecifics = subtypingApplicables.findMaximallySpecificMethods(); if(maximallySpecifics.isEmpty()) { maximallySpecifics = methodInvocationApplicables.findMaximallySpecificMethods(); if(maximallySpecifics.isEmpty()) { maximallySpecifics = variableArityApplicables.findMaximallySpecificMethods(); } } // Now, get a list of the rest of the methods; those that are *not* applicable to the call site signature based // on JLS rules. As paradoxical as that might sound, we have to consider these for dynamic invocation, as they // might match more concrete types passed in invocations. That's why we provisionally call them "invokables". // This is typical for very generic signatures at call sites. Typical example: call site specifies // (Object, Object), and we have a method whose parameter types are (String, int). None of the JLS applicability // rules will trigger, but we must consider the method, as it can be the right match for a concrete invocation. @SuppressWarnings({ "unchecked", "rawtypes" }) final List<SingleDynamicMethod> invokables = (List)methods.clone(); invokables.removeAll(subtypingApplicables.getMethods()); invokables.removeAll(methodInvocationApplicables.getMethods()); invokables.removeAll(variableArityApplicables.getMethods()); for(final Iterator<SingleDynamicMethod> it = invokables.iterator(); it.hasNext();) { final SingleDynamicMethod m = it.next(); if(!isApplicableDynamically(linkerServices, callSiteType, m)) { it.remove(); } } // If no additional methods can apply at invocation time, and there's more than one maximally specific method // based on call site signature, that is a link-time ambiguity. In a static scenario, javac would report an // ambiguity error. if(invokables.isEmpty() && maximallySpecifics.size() > 1) { throw new BootstrapMethodError("Can't choose among " + maximallySpecifics + " for argument types " + callSiteType); } // Merge them all. invokables.addAll(maximallySpecifics); switch(invokables.size()) { case 0: { // No overloads can ever match the call site type return null; } case 1: { // Very lucky, we ended up with a single candidate method handle based on the call site signature; we // can link it very simply by delegating to the SingleDynamicMethod. return invokables.iterator().next().getInvocation(callSiteDescriptor, 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. Note that we're resolving any potential caller sensitive // methods here to their handles, as the OverloadedMethod instance is specific to a call site, so it // has an already determined Lookup. final List<MethodHandle> methodHandles = new ArrayList<>(invokables.size()); final MethodHandles.Lookup lookup = callSiteDescriptor.getLookup(); for(final SingleDynamicMethod method: invokables) { methodHandles.add(method.getTarget(lookup)); } return new OverloadedMethod(methodHandles, this, callSiteType, linkerServices).getInvoker(); } } }
Example 6
Source File: OverloadedDynamicMethod.java From openjdk-8-source with GNU General Public License v2.0 | 4 votes |
@SuppressWarnings("fallthrough") @Override public MethodHandle getInvocation(final CallSiteDescriptor callSiteDescriptor, final LinkerServices linkerServices) { final MethodType callSiteType = callSiteDescriptor.getMethodType(); // First, find all methods applicable to the call site by subtyping (JLS 15.12.2.2) final ApplicableOverloadedMethods subtypingApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_SUBTYPING); // Next, find all methods applicable by method invocation conversion to the call site (JLS 15.12.2.3). final ApplicableOverloadedMethods methodInvocationApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_METHOD_INVOCATION_CONVERSION); // Finally, find all methods applicable by variable arity invocation. (JLS 15.12.2.4). final ApplicableOverloadedMethods variableArityApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_VARIABLE_ARITY); // Find the methods that are maximally specific based on the call site signature List<SingleDynamicMethod> maximallySpecifics = subtypingApplicables.findMaximallySpecificMethods(); if(maximallySpecifics.isEmpty()) { maximallySpecifics = methodInvocationApplicables.findMaximallySpecificMethods(); if(maximallySpecifics.isEmpty()) { maximallySpecifics = variableArityApplicables.findMaximallySpecificMethods(); } } // Now, get a list of the rest of the methods; those that are *not* applicable to the call site signature based // on JLS rules. As paradoxical as that might sound, we have to consider these for dynamic invocation, as they // might match more concrete types passed in invocations. That's why we provisionally call them "invokables". // This is typical for very generic signatures at call sites. Typical example: call site specifies // (Object, Object), and we have a method whose parameter types are (String, int). None of the JLS applicability // rules will trigger, but we must consider the method, as it can be the right match for a concrete invocation. @SuppressWarnings({ "unchecked", "rawtypes" }) final List<SingleDynamicMethod> invokables = (List)methods.clone(); invokables.removeAll(subtypingApplicables.getMethods()); invokables.removeAll(methodInvocationApplicables.getMethods()); invokables.removeAll(variableArityApplicables.getMethods()); for(final Iterator<SingleDynamicMethod> it = invokables.iterator(); it.hasNext();) { final SingleDynamicMethod m = it.next(); if(!isApplicableDynamically(linkerServices, callSiteType, m)) { it.remove(); } } // If no additional methods can apply at invocation time, and there's more than one maximally specific method // based on call site signature, that is a link-time ambiguity. In a static scenario, javac would report an // ambiguity error. if(invokables.isEmpty() && maximallySpecifics.size() > 1) { throw new BootstrapMethodError("Can't choose among " + maximallySpecifics + " for argument types " + callSiteType); } // Merge them all. invokables.addAll(maximallySpecifics); switch(invokables.size()) { case 0: { // No overloads can ever match the call site type return null; } case 1: { // Very lucky, we ended up with a single candidate method handle based on the call site signature; we // can link it very simply by delegating to the SingleDynamicMethod. invokables.iterator().next().getInvocation(callSiteDescriptor, 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. Note that we're resolving any potential caller sensitive // methods here to their handles, as the OverloadedMethod instance is specific to a call site, so it // has an already determined Lookup. final List<MethodHandle> methodHandles = new ArrayList<>(invokables.size()); final MethodHandles.Lookup lookup = callSiteDescriptor.getLookup(); for(SingleDynamicMethod method: invokables) { methodHandles.add(method.getTarget(lookup)); } return new OverloadedMethod(methodHandles, this, callSiteType, linkerServices).getInvoker(); } } }
Example 7
Source File: OverloadedDynamicMethod.java From openjdk-8 with GNU General Public License v2.0 | 4 votes |
@SuppressWarnings("fallthrough") @Override public MethodHandle getInvocation(final CallSiteDescriptor callSiteDescriptor, final LinkerServices linkerServices) { final MethodType callSiteType = callSiteDescriptor.getMethodType(); // First, find all methods applicable to the call site by subtyping (JLS 15.12.2.2) final ApplicableOverloadedMethods subtypingApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_SUBTYPING); // Next, find all methods applicable by method invocation conversion to the call site (JLS 15.12.2.3). final ApplicableOverloadedMethods methodInvocationApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_METHOD_INVOCATION_CONVERSION); // Finally, find all methods applicable by variable arity invocation. (JLS 15.12.2.4). final ApplicableOverloadedMethods variableArityApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_VARIABLE_ARITY); // Find the methods that are maximally specific based on the call site signature List<SingleDynamicMethod> maximallySpecifics = subtypingApplicables.findMaximallySpecificMethods(); if(maximallySpecifics.isEmpty()) { maximallySpecifics = methodInvocationApplicables.findMaximallySpecificMethods(); if(maximallySpecifics.isEmpty()) { maximallySpecifics = variableArityApplicables.findMaximallySpecificMethods(); } } // Now, get a list of the rest of the methods; those that are *not* applicable to the call site signature based // on JLS rules. As paradoxical as that might sound, we have to consider these for dynamic invocation, as they // might match more concrete types passed in invocations. That's why we provisionally call them "invokables". // This is typical for very generic signatures at call sites. Typical example: call site specifies // (Object, Object), and we have a method whose parameter types are (String, int). None of the JLS applicability // rules will trigger, but we must consider the method, as it can be the right match for a concrete invocation. @SuppressWarnings({ "unchecked", "rawtypes" }) final List<SingleDynamicMethod> invokables = (List)methods.clone(); invokables.removeAll(subtypingApplicables.getMethods()); invokables.removeAll(methodInvocationApplicables.getMethods()); invokables.removeAll(variableArityApplicables.getMethods()); for(final Iterator<SingleDynamicMethod> it = invokables.iterator(); it.hasNext();) { final SingleDynamicMethod m = it.next(); if(!isApplicableDynamically(linkerServices, callSiteType, m)) { it.remove(); } } // If no additional methods can apply at invocation time, and there's more than one maximally specific method // based on call site signature, that is a link-time ambiguity. In a static scenario, javac would report an // ambiguity error. if(invokables.isEmpty() && maximallySpecifics.size() > 1) { throw new BootstrapMethodError("Can't choose among " + maximallySpecifics + " for argument types " + callSiteType); } // Merge them all. invokables.addAll(maximallySpecifics); switch(invokables.size()) { case 0: { // No overloads can ever match the call site type return null; } case 1: { // Very lucky, we ended up with a single candidate method handle based on the call site signature; we // can link it very simply by delegating to the SingleDynamicMethod. invokables.iterator().next().getInvocation(callSiteDescriptor, 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. Note that we're resolving any potential caller sensitive // methods here to their handles, as the OverloadedMethod instance is specific to a call site, so it // has an already determined Lookup. final List<MethodHandle> methodHandles = new ArrayList<>(invokables.size()); final MethodHandles.Lookup lookup = callSiteDescriptor.getLookup(); for(SingleDynamicMethod method: invokables) { methodHandles.add(method.getTarget(lookup)); } return new OverloadedMethod(methodHandles, this, callSiteType, linkerServices).getInvoker(); } } }
Example 8
Source File: OverloadedDynamicMethod.java From jdk8u_nashorn with GNU General Public License v2.0 | 4 votes |
@Override public MethodHandle getInvocation(final CallSiteDescriptor callSiteDescriptor, final LinkerServices linkerServices) { final MethodType callSiteType = callSiteDescriptor.getMethodType(); // First, find all methods applicable to the call site by subtyping (JLS 15.12.2.2) final ApplicableOverloadedMethods subtypingApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_SUBTYPING); // Next, find all methods applicable by method invocation conversion to the call site (JLS 15.12.2.3). final ApplicableOverloadedMethods methodInvocationApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_METHOD_INVOCATION_CONVERSION); // Finally, find all methods applicable by variable arity invocation. (JLS 15.12.2.4). final ApplicableOverloadedMethods variableArityApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_VARIABLE_ARITY); // Find the methods that are maximally specific based on the call site signature List<SingleDynamicMethod> maximallySpecifics = subtypingApplicables.findMaximallySpecificMethods(); if(maximallySpecifics.isEmpty()) { maximallySpecifics = methodInvocationApplicables.findMaximallySpecificMethods(); if(maximallySpecifics.isEmpty()) { maximallySpecifics = variableArityApplicables.findMaximallySpecificMethods(); } } // Now, get a list of the rest of the methods; those that are *not* applicable to the call site signature based // on JLS rules. As paradoxical as that might sound, we have to consider these for dynamic invocation, as they // might match more concrete types passed in invocations. That's why we provisionally call them "invokables". // This is typical for very generic signatures at call sites. Typical example: call site specifies // (Object, Object), and we have a method whose parameter types are (String, int). None of the JLS applicability // rules will trigger, but we must consider the method, as it can be the right match for a concrete invocation. @SuppressWarnings({ "unchecked", "rawtypes" }) final List<SingleDynamicMethod> invokables = (List)methods.clone(); invokables.removeAll(subtypingApplicables.getMethods()); invokables.removeAll(methodInvocationApplicables.getMethods()); invokables.removeAll(variableArityApplicables.getMethods()); for(final Iterator<SingleDynamicMethod> it = invokables.iterator(); it.hasNext();) { final SingleDynamicMethod m = it.next(); if(!isApplicableDynamically(linkerServices, callSiteType, m)) { it.remove(); } } // If no additional methods can apply at invocation time, and there's more than one maximally specific method // based on call site signature, that is a link-time ambiguity. In a static scenario, javac would report an // ambiguity error. if(invokables.isEmpty() && maximallySpecifics.size() > 1) { throw new BootstrapMethodError("Can't choose among " + maximallySpecifics + " for argument types " + callSiteType); } // Merge them all. invokables.addAll(maximallySpecifics); switch(invokables.size()) { case 0: { // No overloads can ever match the call site type return null; } case 1: { // Very lucky, we ended up with a single candidate method handle based on the call site signature; we // can link it very simply by delegating to the SingleDynamicMethod. return invokables.iterator().next().getInvocation(callSiteDescriptor, 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. Note that we're resolving any potential caller sensitive // methods here to their handles, as the OverloadedMethod instance is specific to a call site, so it // has an already determined Lookup. final List<MethodHandle> methodHandles = new ArrayList<>(invokables.size()); final MethodHandles.Lookup lookup = callSiteDescriptor.getLookup(); for(final SingleDynamicMethod method: invokables) { methodHandles.add(method.getTarget(lookup)); } return new OverloadedMethod(methodHandles, this, callSiteType, linkerServices).getInvoker(); } } }
Example 9
Source File: OverloadedDynamicMethod.java From nashorn with GNU General Public License v2.0 | 4 votes |
@SuppressWarnings("fallthrough") @Override public MethodHandle getInvocation(final CallSiteDescriptor callSiteDescriptor, final LinkerServices linkerServices) { final MethodType callSiteType = callSiteDescriptor.getMethodType(); // First, find all methods applicable to the call site by subtyping (JLS 15.12.2.2) final ApplicableOverloadedMethods subtypingApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_SUBTYPING); // Next, find all methods applicable by method invocation conversion to the call site (JLS 15.12.2.3). final ApplicableOverloadedMethods methodInvocationApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_METHOD_INVOCATION_CONVERSION); // Finally, find all methods applicable by variable arity invocation. (JLS 15.12.2.4). final ApplicableOverloadedMethods variableArityApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_VARIABLE_ARITY); // Find the methods that are maximally specific based on the call site signature List<SingleDynamicMethod> maximallySpecifics = subtypingApplicables.findMaximallySpecificMethods(); if(maximallySpecifics.isEmpty()) { maximallySpecifics = methodInvocationApplicables.findMaximallySpecificMethods(); if(maximallySpecifics.isEmpty()) { maximallySpecifics = variableArityApplicables.findMaximallySpecificMethods(); } } // Now, get a list of the rest of the methods; those that are *not* applicable to the call site signature based // on JLS rules. As paradoxical as that might sound, we have to consider these for dynamic invocation, as they // might match more concrete types passed in invocations. That's why we provisionally call them "invokables". // This is typical for very generic signatures at call sites. Typical example: call site specifies // (Object, Object), and we have a method whose parameter types are (String, int). None of the JLS applicability // rules will trigger, but we must consider the method, as it can be the right match for a concrete invocation. @SuppressWarnings({ "unchecked", "rawtypes" }) final List<SingleDynamicMethod> invokables = (List)methods.clone(); invokables.removeAll(subtypingApplicables.getMethods()); invokables.removeAll(methodInvocationApplicables.getMethods()); invokables.removeAll(variableArityApplicables.getMethods()); for(final Iterator<SingleDynamicMethod> it = invokables.iterator(); it.hasNext();) { final SingleDynamicMethod m = it.next(); if(!isApplicableDynamically(linkerServices, callSiteType, m)) { it.remove(); } } // If no additional methods can apply at invocation time, and there's more than one maximally specific method // based on call site signature, that is a link-time ambiguity. In a static scenario, javac would report an // ambiguity error. if(invokables.isEmpty() && maximallySpecifics.size() > 1) { throw new BootstrapMethodError("Can't choose among " + maximallySpecifics + " for argument types " + callSiteType); } // Merge them all. invokables.addAll(maximallySpecifics); switch(invokables.size()) { case 0: { // No overloads can ever match the call site type return null; } case 1: { // Very lucky, we ended up with a single candidate method handle based on the call site signature; we // can link it very simply by delegating to the SingleDynamicMethod. invokables.iterator().next().getInvocation(callSiteDescriptor, 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. Note that we're resolving any potential caller sensitive // methods here to their handles, as the OverloadedMethod instance is specific to a call site, so it // has an already determined Lookup. final List<MethodHandle> methodHandles = new ArrayList<>(invokables.size()); final MethodHandles.Lookup lookup = callSiteDescriptor.getLookup(); for(SingleDynamicMethod method: invokables) { methodHandles.add(method.getTarget(lookup)); } return new OverloadedMethod(methodHandles, this, callSiteType, linkerServices).getInvoker(); } } }