提交 bceab689 编写于 作者: P psandoz

8149644: Integrate VarHandles

Reviewed-by: mcimadamore, forax
上级 38a7f975
......@@ -151,6 +151,7 @@ public class Symtab {
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 @@ public class Symtab {
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");
......
......@@ -1062,18 +1062,19 @@ public class Types {
}
/**
* 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;
}
......
......@@ -560,30 +560,37 @@ public class Infer {
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.
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;
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;
}
} 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));
......
......@@ -2461,13 +2461,19 @@ public class Resolve {
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() {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册