2012-10-25 17:34:24 -07:00
|
|
|
/*
|
2013-02-26 17:01:04 -08:00
|
|
|
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
2012-10-25 17:34:24 -07:00
|
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
|
|
*
|
|
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
|
|
* published by the Free Software Foundation. Oracle designates this
|
|
|
|
* particular file as subject to the "Classpath" exception as provided
|
|
|
|
* by Oracle in the LICENSE file that accompanied this code.
|
|
|
|
*
|
|
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
|
|
* accompanied this code).
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License version
|
|
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*
|
|
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
|
|
* questions.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package java.lang.invoke;
|
|
|
|
|
2013-07-11 14:02:20 +01:00
|
|
|
import java.io.Serializable;
|
|
|
|
import java.util.Arrays;
|
|
|
|
|
2012-10-25 17:34:24 -07:00
|
|
|
/**
|
|
|
|
* <p>Bootstrap methods for converting lambda expressions and method references to functional interface objects.</p>
|
|
|
|
*
|
|
|
|
* <p>For every lambda expressions or method reference in the source code, there is a target type which is a
|
|
|
|
* functional interface. Evaluating a lambda expression produces an object of its target type. The mechanism for
|
|
|
|
* evaluating lambda expressions is to invoke an invokedynamic call site, which takes arguments describing the sole
|
|
|
|
* method of the functional interface and the implementation method, and returns an object (the lambda object) that
|
|
|
|
* implements the target type. Methods of the lambda object invoke the implementation method. For method
|
|
|
|
* references, the implementation method is simply the referenced method; for lambda expressions, the
|
|
|
|
* implementation method is produced by the compiler based on the body of the lambda expression. The methods in
|
|
|
|
* this file are the bootstrap methods for those invokedynamic call sites, called lambda factories, and the
|
|
|
|
* bootstrap methods responsible for linking the lambda factories are called lambda meta-factories.
|
|
|
|
*
|
|
|
|
* <p>The bootstrap methods in this class take the information about the functional interface, the implementation
|
|
|
|
* method, and the static types of the captured lambda arguments, and link a call site which, when invoked,
|
|
|
|
* produces the lambda object.
|
|
|
|
*
|
2013-02-16 12:36:54 -08:00
|
|
|
* <p>When parameterized types are used, the instantiated type of the functional interface method may be different
|
|
|
|
* from that in the functional interface. For example, consider
|
2013-07-11 14:02:20 +01:00
|
|
|
* {@code interface I<T> { int m(T x); }} if this functional interface type is used in a lambda
|
|
|
|
* {@code I<Byte>; v = ...}, we need both the actual functional interface method which has the signature
|
|
|
|
* {@code (Object)int} and the erased instantiated type of the functional interface method (or simply
|
2013-02-16 12:36:54 -08:00
|
|
|
* <I>instantiated method type</I>), which has signature
|
2013-07-11 14:02:20 +01:00
|
|
|
* {@code (Byte)int}.
|
2012-10-25 17:34:24 -07:00
|
|
|
*
|
|
|
|
* <p>The argument list of the implementation method and the argument list of the functional interface method(s)
|
|
|
|
* may differ in several ways. The implementation methods may have additional arguments to accommodate arguments
|
|
|
|
* captured by the lambda expression; there may also be differences resulting from permitted adaptations of
|
|
|
|
* arguments, such as casting, boxing, unboxing, and primitive widening. They may also differ because of var-args,
|
|
|
|
* but this is expected to be handled by the compiler.
|
|
|
|
*
|
|
|
|
* <p>Invokedynamic call sites have two argument lists: a static argument list and a dynamic argument list. The
|
|
|
|
* static argument list lives in the constant pool; the dynamic argument list lives on the operand stack at
|
|
|
|
* invocation time. The bootstrap method has access to the entire static argument list (which in this case,
|
|
|
|
* contains method handles describing the implementation method and the canonical functional interface method),
|
|
|
|
* as well as a method signature describing the number and static types (but not the values) of the dynamic
|
|
|
|
* arguments, and the static return type of the invokedynamic site.
|
|
|
|
*
|
|
|
|
* <p>The implementation method is described with a method handle. In theory, any method handle could be used.
|
|
|
|
* Currently supported are method handles representing invocation of virtual, interface, constructor and static
|
|
|
|
* methods.
|
|
|
|
*
|
|
|
|
* <p>Assume:
|
|
|
|
* <ul>
|
|
|
|
* <li>the functional interface method has N arguments, of types (U1, U2, ... Un) and return type Ru</li>
|
|
|
|
* <li>then the instantiated method type also has N arguments, of types (T1, T2, ... Tn) and return type Rt</li>
|
|
|
|
* <li>the implementation method has M arguments, of types (A1..Am) and return type Ra,</li>
|
|
|
|
* <li>the dynamic argument list has K arguments of types (D1..Dk), and the invokedynamic return site has
|
|
|
|
* type Rd</li>
|
|
|
|
* <li>the functional interface type is F</li>
|
|
|
|
* </ul>
|
|
|
|
*
|
|
|
|
* <p>The following signature invariants must hold:
|
|
|
|
* <ul>
|
|
|
|
* <li>Rd is a subtype of F</li>
|
|
|
|
* <li>For i=1..N, Ti is a subtype of Ui</li>
|
|
|
|
* <li>Either Rt and Ru are primitive and are the same type, or both are reference types and
|
|
|
|
* Rt is a subtype of Ru</li>
|
|
|
|
* <li>If the implementation method is a static method:
|
|
|
|
* <ul>
|
|
|
|
* <li>K + N = M</li>
|
|
|
|
* <li>For i=1..K, Di = Ai</li>
|
|
|
|
* <li>For i=1..N, Ti is adaptable to Aj, where j=i+k</li>
|
|
|
|
* </ul></li>
|
|
|
|
* <li>If the implementation method is an instance method:
|
|
|
|
* <ul>
|
|
|
|
* <li>K + N = M + 1</li>
|
|
|
|
* <li>D1 must be a subtype of the enclosing class for the implementation method</li>
|
|
|
|
* <li>For i=2..K, Di = Aj, where j=i-1</li>
|
|
|
|
* <li>For i=1..N, Ti is adaptable to Aj, where j=i+k-1</li>
|
|
|
|
* </ul></li>
|
|
|
|
* <li>The return type Rt is void, or the return type Ra is not void and is adaptable to Rt</li>
|
|
|
|
* </ul>
|
|
|
|
*
|
|
|
|
* <p>Note that the potentially parameterized implementation return type provides the value for the SAM. Whereas
|
|
|
|
* the completely known instantiated return type is adapted to the implementation arguments. Because the
|
|
|
|
* instantiated type of the implementation method is not available, the adaptability of return types cannot be
|
|
|
|
* checked as precisely at link-time as the arguments can be checked. Thus a loose version of link-time checking is
|
|
|
|
* done on return type, while a strict version is applied to arguments.
|
|
|
|
*
|
|
|
|
* <p>A type Q is considered adaptable to S as follows:
|
2013-06-27 19:02:02 -07:00
|
|
|
* <table summary="adaptable types">
|
2012-10-25 17:34:24 -07:00
|
|
|
* <tr><th>Q</th><th>S</th><th>Link-time checks</th><th>Capture-time checks</th></tr>
|
|
|
|
* <tr>
|
|
|
|
* <td>Primitive</td><td>Primitive</td>
|
|
|
|
* <td>Q can be converted to S via a primitive widening conversion</td>
|
|
|
|
* <td>None</td>
|
|
|
|
* </tr>
|
|
|
|
* <tr>
|
|
|
|
* <td>Primitive</td><td>Reference</td>
|
|
|
|
* <td>S is a supertype of the Wrapper(Q)</td>
|
|
|
|
* <td>Cast from Wrapper(Q) to S</td>
|
|
|
|
* </tr>
|
|
|
|
* <tr>
|
|
|
|
* <td>Reference</td><td>Primitive</td>
|
|
|
|
* <td>strict: Q is a primitive wrapper and Primitive(Q) can be widened to S
|
|
|
|
* <br>loose: If Q is a primitive wrapper, check that Primitive(Q) can be widened to S</td>
|
|
|
|
* <td>If Q is not a primitive wrapper, cast Q to the base Wrapper(S); for example Number for numeric types</td>
|
|
|
|
* </tr>
|
|
|
|
* <tr>
|
|
|
|
* <td>Reference</td><td>Reference</td>
|
|
|
|
* <td>strict: S is a supertype of Q
|
|
|
|
* <br>loose: none</td>
|
|
|
|
* <td>Cast from Q to S</td>
|
|
|
|
* </tr>
|
|
|
|
* </table>
|
|
|
|
*
|
2013-07-11 14:02:20 +01:00
|
|
|
* The default bootstrap ({@link #metafactory}) represents the common cases and uses an optimized protocol.
|
|
|
|
* Alternate bootstraps (e.g., {@link #altMetafactory}) exist to support uncommon cases such as serialization
|
2013-02-16 12:36:54 -08:00
|
|
|
* or additional marker superinterfaces.
|
2012-10-25 17:34:24 -07:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
public class LambdaMetafactory {
|
|
|
|
|
2013-07-11 14:02:20 +01:00
|
|
|
/** Flag for alternate metafactories indicating the lambda object is
|
|
|
|
* must to be serializable */
|
2013-02-16 12:36:54 -08:00
|
|
|
public static final int FLAG_SERIALIZABLE = 1 << 0;
|
|
|
|
|
2012-10-25 17:34:24 -07:00
|
|
|
/**
|
2013-07-11 14:02:20 +01:00
|
|
|
* Flag for alternate metafactories indicating the lambda object implements
|
|
|
|
* other marker interfaces
|
2013-02-16 12:36:54 -08:00
|
|
|
* besides Serializable
|
|
|
|
*/
|
|
|
|
public static final int FLAG_MARKERS = 1 << 1;
|
|
|
|
|
2013-07-11 14:02:20 +01:00
|
|
|
/**
|
|
|
|
* Flag for alternate metafactories indicating the lambda object requires
|
|
|
|
* additional bridge methods
|
|
|
|
*/
|
|
|
|
public static final int FLAG_BRIDGES = 1 << 2;
|
|
|
|
|
2013-02-16 12:36:54 -08:00
|
|
|
private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
|
2013-07-11 14:02:20 +01:00
|
|
|
private static final MethodType[] EMPTY_MT_ARRAY = new MethodType[0];
|
2013-02-16 12:36:54 -08:00
|
|
|
|
2013-06-27 19:02:02 -07:00
|
|
|
/**
|
2013-07-11 14:02:20 +01:00
|
|
|
* Standard meta-factory for conversion of lambda expressions or method
|
|
|
|
* references to functional interfaces.
|
2012-10-25 17:34:24 -07:00
|
|
|
*
|
2013-07-11 14:02:20 +01:00
|
|
|
* @param caller Stacked automatically by VM; represents a lookup context
|
|
|
|
* with the accessibility privileges of the caller.
|
|
|
|
* @param invokedName Stacked automatically by VM; the name of the invoked
|
|
|
|
* method as it appears at the call site.
|
|
|
|
* Used as the name of the functional interface method
|
|
|
|
* to which the lambda or method reference is being
|
|
|
|
* converted.
|
|
|
|
* @param invokedType Stacked automatically by VM; the signature of the
|
|
|
|
* invoked method, which includes the expected static
|
|
|
|
* type of the returned lambda object, and the static
|
|
|
|
* types of the captured arguments for the lambda.
|
|
|
|
* In the event that the implementation method is an
|
|
|
|
* instance method, the first argument in the invocation
|
|
|
|
* signature will correspond to the receiver.
|
|
|
|
* @param samMethodType MethodType of the method in the functional interface
|
|
|
|
* to which the lambda or method reference is being
|
|
|
|
* converted, represented as a MethodType.
|
2013-10-22 15:12:22 -07:00
|
|
|
* @param implMethod A direct method handle describing the implementation
|
|
|
|
* method which should be called (with suitable adaptation
|
|
|
|
* of argument types, return types, and adjustment for
|
|
|
|
* captured arguments) when methods of the resulting
|
|
|
|
* functional interface instance are invoked.
|
2013-07-11 14:02:20 +01:00
|
|
|
* @param instantiatedMethodType The signature of the primary functional
|
|
|
|
* interface method after type variables
|
|
|
|
* are substituted with their instantiation
|
2013-10-22 15:12:22 -07:00
|
|
|
* from the capture site.
|
2013-07-11 14:02:20 +01:00
|
|
|
* @return a CallSite, which, when invoked, will return an instance of the
|
|
|
|
* functional interface
|
|
|
|
* @throws ReflectiveOperationException if the caller is not able to
|
|
|
|
* reconstruct one of the method handles
|
|
|
|
* @throws LambdaConversionException If any of the meta-factory protocol
|
|
|
|
* invariants are violated
|
2012-10-25 17:34:24 -07:00
|
|
|
*/
|
2013-07-11 14:02:20 +01:00
|
|
|
public static CallSite metafactory(MethodHandles.Lookup caller,
|
2012-10-25 17:34:24 -07:00
|
|
|
String invokedName,
|
|
|
|
MethodType invokedType,
|
2013-07-11 14:02:20 +01:00
|
|
|
MethodType samMethodType,
|
2012-10-25 17:34:24 -07:00
|
|
|
MethodHandle implMethod,
|
|
|
|
MethodType instantiatedMethodType)
|
|
|
|
throws ReflectiveOperationException, LambdaConversionException {
|
|
|
|
AbstractValidatingLambdaMetafactory mf;
|
2013-07-11 14:02:20 +01:00
|
|
|
mf = new InnerClassLambdaMetafactory(caller, invokedType,
|
|
|
|
invokedName, samMethodType,
|
|
|
|
implMethod, instantiatedMethodType,
|
|
|
|
false, EMPTY_CLASS_ARRAY, EMPTY_MT_ARRAY);
|
2013-02-16 12:36:54 -08:00
|
|
|
mf.validateMetafactoryArgs();
|
|
|
|
return mf.buildCallSite();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2013-07-11 14:02:20 +01:00
|
|
|
* Alternate meta-factory for conversion of lambda expressions or method
|
|
|
|
* references to functional interfaces, which supports serialization and
|
|
|
|
* other uncommon options.
|
2013-02-16 12:36:54 -08:00
|
|
|
*
|
2013-10-22 15:12:22 -07:00
|
|
|
* <p>The declared argument list for this method is:
|
2013-02-16 12:36:54 -08:00
|
|
|
*
|
2013-10-22 15:12:22 -07:00
|
|
|
* <pre>{@code
|
2013-07-11 14:02:20 +01:00
|
|
|
* CallSite altMetafactory(MethodHandles.Lookup caller,
|
2013-02-16 12:36:54 -08:00
|
|
|
* String invokedName,
|
|
|
|
* MethodType invokedType,
|
|
|
|
* Object... args)
|
2013-10-22 15:12:22 -07:00
|
|
|
* }</pre>
|
2013-02-16 12:36:54 -08:00
|
|
|
*
|
2013-10-22 15:12:22 -07:00
|
|
|
* <p>but it behaves as if the argument list is as follows, where names that
|
|
|
|
* appear in the argument list for
|
|
|
|
* {@link #metafactory(MethodHandles.Lookup, String, MethodType, MethodType, MethodHandle, MethodType)}
|
|
|
|
* have the same specification as in that method:
|
2013-02-16 12:36:54 -08:00
|
|
|
*
|
2013-10-22 15:12:22 -07:00
|
|
|
* <pre>{@code
|
2013-07-11 14:02:20 +01:00
|
|
|
* CallSite altMetafactory(MethodHandles.Lookup caller,
|
2013-02-16 12:36:54 -08:00
|
|
|
* String invokedName,
|
|
|
|
* MethodType invokedType,
|
2013-07-11 14:02:20 +01:00
|
|
|
* MethodType samMethodType
|
2013-02-16 12:36:54 -08:00
|
|
|
* MethodHandle implMethod,
|
|
|
|
* MethodType instantiatedMethodType,
|
|
|
|
* int flags,
|
|
|
|
* int markerInterfaceCount, // IF flags has MARKERS set
|
|
|
|
* Class... markerInterfaces // IF flags has MARKERS set
|
2013-07-11 14:02:20 +01:00
|
|
|
* int bridgeCount, // IF flags has BRIDGES set
|
|
|
|
* MethodType... bridges // IF flags has BRIDGES set
|
2013-02-16 12:36:54 -08:00
|
|
|
* )
|
2013-10-22 15:12:22 -07:00
|
|
|
* }</pre>
|
2013-02-16 12:36:54 -08:00
|
|
|
*
|
2013-10-22 15:12:22 -07:00
|
|
|
* <p>If the flags contains {@code FLAG_SERIALIZABLE}, or one of the marker
|
|
|
|
* interfaces extends {@link Serializable}, the metafactory will link the
|
|
|
|
* call site to one that produces a serializable lambda. In addition to
|
|
|
|
* the lambda instance implementing {@code Serializable}, it will have a
|
|
|
|
* {@code writeReplace} method that returns an appropriate {@link
|
|
|
|
* SerializedLambda}, and an appropriate {@code $deserializeLambda$}
|
|
|
|
* method.
|
2013-02-16 12:36:54 -08:00
|
|
|
*
|
2013-07-11 14:02:20 +01:00
|
|
|
* @param caller Stacked automatically by VM; represents a lookup context
|
|
|
|
* with the accessibility privileges of the caller.
|
|
|
|
* @param invokedName Stacked automatically by VM; the name of the invoked
|
|
|
|
* method as it appears at the call site.
|
|
|
|
* Used as the name of the functional interface method
|
|
|
|
* to which the lambda or method reference is being
|
|
|
|
* converted.
|
|
|
|
* @param invokedType Stacked automatically by VM; the signature of the
|
|
|
|
* invoked method, which includes the expected static
|
|
|
|
* type of the returned lambda object, and the static
|
|
|
|
* types of the captured arguments for the lambda.
|
|
|
|
* In the event that the implementation method is an
|
|
|
|
* instance method, the first argument in the invocation
|
|
|
|
* signature will correspond to the receiver.
|
2013-10-22 15:12:22 -07:00
|
|
|
* @param args flags and optional arguments, as described above.
|
2013-07-11 14:02:20 +01:00
|
|
|
* @return a CallSite, which, when invoked, will return an instance of the
|
|
|
|
* functional interface
|
|
|
|
* @throws ReflectiveOperationException if the caller is not able to
|
|
|
|
* reconstruct one of the method handles
|
|
|
|
* @throws LambdaConversionException If any of the meta-factory protocol
|
|
|
|
* invariants are violated
|
2013-02-16 12:36:54 -08:00
|
|
|
*/
|
2013-07-11 14:02:20 +01:00
|
|
|
public static CallSite altMetafactory(MethodHandles.Lookup caller,
|
2013-02-16 12:36:54 -08:00
|
|
|
String invokedName,
|
|
|
|
MethodType invokedType,
|
|
|
|
Object... args)
|
|
|
|
throws ReflectiveOperationException, LambdaConversionException {
|
2013-07-11 14:02:20 +01:00
|
|
|
MethodType samMethodType = (MethodType)args[0];
|
2013-02-16 12:36:54 -08:00
|
|
|
MethodHandle implMethod = (MethodHandle)args[1];
|
|
|
|
MethodType instantiatedMethodType = (MethodType)args[2];
|
|
|
|
int flags = (Integer) args[3];
|
|
|
|
Class<?>[] markerInterfaces;
|
2013-07-11 14:02:20 +01:00
|
|
|
MethodType[] bridges;
|
2013-02-16 12:36:54 -08:00
|
|
|
int argIndex = 4;
|
|
|
|
if ((flags & FLAG_MARKERS) != 0) {
|
|
|
|
int markerCount = (Integer) args[argIndex++];
|
|
|
|
markerInterfaces = new Class<?>[markerCount];
|
|
|
|
System.arraycopy(args, argIndex, markerInterfaces, 0, markerCount);
|
|
|
|
argIndex += markerCount;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
markerInterfaces = EMPTY_CLASS_ARRAY;
|
2013-07-11 14:02:20 +01:00
|
|
|
if ((flags & FLAG_BRIDGES) != 0) {
|
|
|
|
int bridgeCount = (Integer) args[argIndex++];
|
|
|
|
bridges = new MethodType[bridgeCount];
|
|
|
|
System.arraycopy(args, argIndex, bridges, 0, bridgeCount);
|
|
|
|
argIndex += bridgeCount;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
bridges = EMPTY_MT_ARRAY;
|
|
|
|
|
|
|
|
boolean foundSerializableSupertype = Serializable.class.isAssignableFrom(invokedType.returnType());
|
|
|
|
for (Class<?> c : markerInterfaces)
|
|
|
|
foundSerializableSupertype |= Serializable.class.isAssignableFrom(c);
|
|
|
|
boolean isSerializable = ((flags & LambdaMetafactory.FLAG_SERIALIZABLE) != 0)
|
|
|
|
|| foundSerializableSupertype;
|
|
|
|
|
|
|
|
if (isSerializable && !foundSerializableSupertype) {
|
|
|
|
markerInterfaces = Arrays.copyOf(markerInterfaces, markerInterfaces.length + 1);
|
|
|
|
markerInterfaces[markerInterfaces.length-1] = Serializable.class;
|
|
|
|
}
|
|
|
|
|
|
|
|
AbstractValidatingLambdaMetafactory mf
|
|
|
|
= new InnerClassLambdaMetafactory(caller, invokedType,
|
|
|
|
invokedName, samMethodType,
|
|
|
|
implMethod,
|
|
|
|
instantiatedMethodType,
|
|
|
|
isSerializable,
|
|
|
|
markerInterfaces, bridges);
|
2012-10-25 17:34:24 -07:00
|
|
|
mf.validateMetafactoryArgs();
|
|
|
|
return mf.buildCallSite();
|
|
|
|
}
|
|
|
|
}
|