--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java Tue Mar 15 14:50:00 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java Thu Mar 24 11:21:37 2016 +0100
@@ -151,6 +151,7 @@
public final Type cloneableType;
public final Type serializableType;
public final Type serializedLambdaType;
+ public final Type varHandleType;
public final Type methodHandleType;
public final Type methodHandleLookupType;
public final Type methodTypeType;
@@ -419,6 +420,7 @@
throwableType = enterClass("java.lang.Throwable");
serializableType = enterClass("java.io.Serializable");
serializedLambdaType = enterClass("java.lang.invoke.SerializedLambda");
+ varHandleType = enterClass("java.lang.invoke.VarHandle");
methodHandleType = enterClass("java.lang.invoke.MethodHandle");
methodHandleLookupType = enterClass("java.lang.invoke.MethodHandles$Lookup");
methodTypeType = enterClass("java.lang.invoke.MethodType");
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Tue Mar 15 14:50:00 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Thu Mar 24 11:21:37 2016 +0100
@@ -1062,18 +1062,19 @@
}
/**
- * A polymorphic signature method (JLS 15.12.3) is a method that
- * (i) is declared in the java.lang.invoke.MethodHandle class, (ii) takes
- * a single variable arity parameter (iii) whose declared type is Object[],
- * (iv) has a return type of Object and (v) is native.
+ * A polymorphic signature method (JLS 15.12.3) is a method that
+ * (i) is declared in the java.lang.invoke.MethodHandle/VarHandle classes;
+ * (ii) takes a single variable arity parameter;
+ * (iii) whose declared type is Object[];
+ * (iv) has any return type, Object signifying a polymorphic return type; and
+ * (v) is native.
*/
public boolean isSignaturePolymorphic(MethodSymbol msym) {
List<Type> argtypes = msym.type.getParameterTypes();
return (msym.flags_field & NATIVE) != 0 &&
- msym.owner == syms.methodHandleType.tsym &&
+ (msym.owner == syms.methodHandleType.tsym || msym.owner == syms.varHandleType.tsym) &&
argtypes.tail.tail == null &&
argtypes.head.hasTag(TypeTag.ARRAY) &&
- msym.type.getReturnType().tsym == syms.objectType.tsym &&
((ArrayType)argtypes.head).elemtype.tsym == syms.objectType.tsym;
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java Tue Mar 15 14:50:00 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java Thu Mar 24 11:21:37 2016 +0100
@@ -560,30 +560,37 @@
List<Type> argtypes) {
final Type restype;
- //The return type for a polymorphic signature call is computed from
- //the enclosing tree E, as follows: if E is a cast, then use the
- //target type of the cast expression as a return type; if E is an
- //expression statement, the return type is 'void' - otherwise the
- //return type is simply 'Object'. A correctness check ensures that
- //env.next refers to the lexically enclosing environment in which
- //the polymorphic signature call environment is nested.
+ if (spMethod == null || types.isSameType(spMethod.getReturnType(), syms.objectType, true)) {
+ // The return type of the polymorphic signature is polymorphic,
+ // and is computed from the enclosing tree E, as follows:
+ // if E is a cast, then use the target type of the cast expression
+ // as a return type; if E is an expression statement, the return
+ // type is 'void'; otherwise
+ // the return type is simply 'Object'. A correctness check ensures
+ // that env.next refers to the lexically enclosing environment in
+ // which the polymorphic signature call environment is nested.
- switch (env.next.tree.getTag()) {
- case TYPECAST:
- JCTypeCast castTree = (JCTypeCast)env.next.tree;
- restype = (TreeInfo.skipParens(castTree.expr) == env.tree) ?
- castTree.clazz.type :
- syms.objectType;
- break;
- case EXEC:
- JCTree.JCExpressionStatement execTree =
- (JCTree.JCExpressionStatement)env.next.tree;
- restype = (TreeInfo.skipParens(execTree.expr) == env.tree) ?
- syms.voidType :
- syms.objectType;
- break;
- default:
- restype = syms.objectType;
+ switch (env.next.tree.getTag()) {
+ case TYPECAST:
+ JCTypeCast castTree = (JCTypeCast)env.next.tree;
+ restype = (TreeInfo.skipParens(castTree.expr) == env.tree) ?
+ castTree.clazz.type :
+ syms.objectType;
+ break;
+ case EXEC:
+ JCTree.JCExpressionStatement execTree =
+ (JCTree.JCExpressionStatement)env.next.tree;
+ restype = (TreeInfo.skipParens(execTree.expr) == env.tree) ?
+ syms.voidType :
+ syms.objectType;
+ break;
+ default:
+ restype = syms.objectType;
+ }
+ } else {
+ // The return type of the polymorphic signature is fixed
+ // (not polymorphic)
+ restype = spMethod.getReturnType();
}
List<Type> paramtypes = argtypes.map(new ImplicitArgType(spMethod, resolveContext.step));
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Tue Mar 15 14:50:00 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Thu Mar 24 11:21:37 2016 +0100
@@ -2461,13 +2461,19 @@
Type mtype = infer.instantiatePolymorphicSignatureInstance(env,
(MethodSymbol)spMethod, currentResolutionContext, argtypes);
for (Symbol sym : polymorphicSignatureScope.getSymbolsByName(spMethod.name)) {
- if (types.isSameType(mtype, sym.type)) {
- return sym;
+ // Check that there is already a method symbol for the method
+ // type and owner
+ if (types.isSameType(mtype, sym.type) &&
+ spMethod.owner == sym.owner) {
+ return sym;
}
}
- // create the desired method
- long flags = ABSTRACT | HYPOTHETICAL | spMethod.flags() & Flags.AccessFlags;
+ // Create the desired method
+ // Retain static modifier is to support invocations to
+ // MethodHandle.linkTo* methods
+ long flags = ABSTRACT | HYPOTHETICAL |
+ spMethod.flags() & (Flags.AccessFlags | Flags.STATIC);
Symbol msym = new MethodSymbol(flags, spMethod.name, mtype, spMethod.owner) {
@Override
public Symbol baseSymbol() {