提交 b51bae99 编写于 作者: M mcimadamore

6992698: JSR 292: remove support for transient syntax in polymorphic signature calls

Summary: special syntax to denote indy return type through type parameters should be removed (and cast shall be used instead)
Reviewed-by: jjg, jrose
上级 d094ce29
......@@ -126,7 +126,6 @@ public class Symtab {
public final Type serializableType;
public final Type methodHandleType;
public final Type polymorphicSignatureType;
public final Type invokeDynamicType;
public final Type throwableType;
public final Type errorType;
public final Type illegalArgumentExceptionType;
......@@ -422,7 +421,6 @@ public class Symtab {
serializableType = enterClass("java.io.Serializable");
methodHandleType = enterClass("java.dyn.MethodHandle");
polymorphicSignatureType = enterClass("java.dyn.MethodHandle$PolymorphicSignature");
invokeDynamicType = enterClass("java.dyn.InvokeDynamic");
errorType = enterClass("java.lang.Error");
illegalArgumentExceptionType = enterClass("java.lang.IllegalArgumentException");
exceptionType = enterClass("java.lang.Exception");
......
......@@ -1334,7 +1334,6 @@ public class Attr extends JCTree.Visitor {
// The types of the actual method type arguments.
List<Type> typeargtypes = null;
boolean typeargtypesNonRefOK = false;
Name methName = TreeInfo.name(tree.meth);
......@@ -1463,21 +1462,7 @@ public class Attr extends JCTree.Visitor {
restype.tsym);
}
// Special case logic for JSR 292 types.
if (rs.allowTransitionalJSR292 &&
tree.meth.getTag() == JCTree.SELECT &&
!typeargtypes.isEmpty()) {
JCFieldAccess mfield = (JCFieldAccess) tree.meth;
// MethodHandle.<T>invoke(abc) and InvokeDynamic.<T>foo(abc)
// has type <T>, and T can be a primitive type.
if (mfield.sym != null &&
mfield.sym.isPolymorphicSignatureInstance())
typeargtypesNonRefOK = true;
}
if (!(rs.allowTransitionalJSR292 && typeargtypesNonRefOK)) {
chk.checkRefTypes(tree.typeargs, typeargtypes);
}
// Check that value of resulting type is admissible in the
// current context. Also, capture the return type
......
......@@ -1375,8 +1375,9 @@ public class Flow extends TreeScanner {
//where
private boolean is292targetTypeCast(JCTypeCast tree) {
boolean is292targetTypeCast = false;
if (tree.expr.getTag() == JCTree.APPLY) {
JCMethodInvocation apply = (JCMethodInvocation)tree.expr;
JCExpression expr = TreeInfo.skipParens(tree.expr);
if (expr.getTag() == JCTree.APPLY) {
JCMethodInvocation apply = (JCMethodInvocation)expr;
Symbol sym = TreeInfo.symbol(apply.meth);
is292targetTypeCast = sym != null &&
sym.kind == MTH &&
......
......@@ -27,6 +27,7 @@ package com.sun.tools.javac.comp;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCTypeCast;
import com.sun.tools.javac.tree.TreeInfo;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.code.*;
......@@ -538,18 +539,15 @@ public class Infer {
/**
* Compute a synthetic method type corresponding to the requested polymorphic
* method signature. If no explicit return type is supplied, a provisional
* return type is computed (just Object in case of non-transitional 292)
* method signature. The target return type is computed from the immediately
* enclosing scope surrounding the polymorphic-signature call.
*/
Type instantiatePolymorphicSignatureInstance(Env<AttrContext> env, Type site,
Name name,
MethodSymbol spMethod, // sig. poly. method or null if none
List<Type> argtypes,
List<Type> typeargtypes) {
List<Type> argtypes) {
final Type restype;
if (rs.allowTransitionalJSR292 && typeargtypes.nonEmpty()) {
restype = typeargtypes.head;
} else {
//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
......@@ -561,21 +559,20 @@ public class Infer {
switch (env.next.tree.getTag()) {
case JCTree.TYPECAST:
JCTypeCast castTree = (JCTypeCast)env.next.tree;
restype = (castTree.expr == env.tree) ?
restype = (TreeInfo.skipParens(castTree.expr) == env.tree) ?
castTree.clazz.type :
syms.objectType;
break;
case JCTree.EXEC:
JCTree.JCExpressionStatement execTree =
(JCTree.JCExpressionStatement)env.next.tree;
restype = (execTree.expr == env.tree) ?
restype = (TreeInfo.skipParens(execTree.expr) == env.tree) ?
syms.voidType :
syms.objectType;
break;
default:
restype = syms.objectType;
}
}
List<Type> paramtypes = Type.map(argtypes, implicitArgType);
List<Type> exType = spMethod != null ?
......
......@@ -70,8 +70,6 @@ public class Resolve {
public final boolean boxingEnabled; // = source.allowBoxing();
public final boolean varargsEnabled; // = source.allowVarargs();
public final boolean allowMethodHandles;
public final boolean allowInvokeDynamic;
public final boolean allowTransitionalJSR292;
private final boolean debugResolve;
Scope polymorphicSignatureScope;
......@@ -111,13 +109,8 @@ public class Resolve {
varargsEnabled = source.allowVarargs();
Options options = Options.instance(context);
debugResolve = options.isSet("debugresolve");
allowTransitionalJSR292 = options.isSet("allowTransitionalJSR292");
Target target = Target.instance(context);
allowMethodHandles = allowTransitionalJSR292 ||
target.hasMethodHandles();
allowInvokeDynamic = (allowTransitionalJSR292 ||
target.hasInvokedynamic()) &&
options.isSet("invokedynamic");
allowMethodHandles = target.hasMethodHandles();
polymorphicSignatureScope = new Scope(syms.noSymbol);
inapplicableMethodException = new InapplicableMethodException(diags);
......@@ -336,8 +329,7 @@ public class Resolve {
boolean useVarargs,
Warner warn)
throws Infer.InferenceException {
boolean polymorphicSignature = (m.isPolymorphicSignatureGeneric() && allowMethodHandles) ||
isTransitionalDynamicCallSite(site, m);
boolean polymorphicSignature = m.isPolymorphicSignatureGeneric() && allowMethodHandles;
if (useVarargs && (m.flags() & VARARGS) == 0)
throw inapplicableMethodException.setMessage(null);
Type mt = types.memberType(site, m);
......@@ -346,10 +338,7 @@ public class Resolve {
// need to inferred.
List<Type> tvars = env.info.tvars;
if (typeargtypes == null) typeargtypes = List.nil();
if (allowTransitionalJSR292 && polymorphicSignature && typeargtypes.nonEmpty()) {
//transitional 292 call sites might have wrong number of targs
}
else if (mt.tag != FORALL && typeargtypes.nonEmpty()) {
if (mt.tag != FORALL && typeargtypes.nonEmpty()) {
// This is not a polymorphic method, but typeargs are supplied
// which is fine, see JLS3 15.12.2.1
} else if (mt.tag == FORALL && typeargtypes.nonEmpty()) {
......@@ -387,7 +376,7 @@ public class Resolve {
if (instNeeded)
return polymorphicSignature ?
infer.instantiatePolymorphicSignatureInstance(env, site, m.name, (MethodSymbol)m, argtypes, typeargtypes) :
infer.instantiatePolymorphicSignatureInstance(env, site, m.name, (MethodSymbol)m, argtypes) :
infer.instantiateMethod(env,
tvars,
(MethodType)mt,
......@@ -402,14 +391,6 @@ public class Resolve {
return mt;
}
boolean isTransitionalDynamicCallSite(Type site, Symbol sym) {
return allowTransitionalJSR292 && // old logic that doesn't use annotations
!sym.isPolymorphicSignatureInstance() &&
((allowMethodHandles && site == syms.methodHandleType && // invokeExact, invokeGeneric, invoke
(sym.name == names.invoke && sym.isPolymorphicSignatureGeneric())) ||
(site == syms.invokeDynamicType && allowInvokeDynamic)); // InvokeDynamic.XYZ
}
/** Same but returns null instead throwing a NoInstanceException
*/
Type instantiate(Env<AttrContext> env,
......@@ -1412,12 +1393,11 @@ public class Resolve {
steps = steps.tail;
}
if (sym.kind >= AMBIGUOUS) {
if (site.tsym.isPolymorphicSignatureGeneric() ||
isTransitionalDynamicCallSite(site, sym)) {
if (site.tsym.isPolymorphicSignatureGeneric()) {
//polymorphic receiver - synthesize new method symbol
env.info.varArgs = false;
sym = findPolymorphicSignatureInstance(env,
site, name, null, argtypes, typeargtypes);
site, name, null, argtypes);
}
else {
//if nothing is found return the 'first' error
......@@ -1431,7 +1411,7 @@ public class Resolve {
//non-instantiated polymorphic signature - synthesize new method symbol
env.info.varArgs = false;
sym = findPolymorphicSignatureInstance(env,
site, name, (MethodSymbol)sym, argtypes, typeargtypes);
site, name, (MethodSymbol)sym, argtypes);
}
return sym;
}
......@@ -1449,15 +1429,9 @@ public class Resolve {
Symbol findPolymorphicSignatureInstance(Env<AttrContext> env, Type site,
Name name,
MethodSymbol spMethod, // sig. poly. method or null if none
List<Type> argtypes,
List<Type> typeargtypes) {
if (typeargtypes.nonEmpty() && (site.tsym.isPolymorphicSignatureGeneric() ||
(spMethod != null && spMethod.isPolymorphicSignatureGeneric()))) {
log.warning(env.tree.pos(), "type.parameter.on.polymorphic.signature");
}
List<Type> argtypes) {
Type mtype = infer.instantiatePolymorphicSignatureInstance(env,
site, name, spMethod, argtypes, typeargtypes);
site, name, spMethod, argtypes);
long flags = ABSTRACT | HYPOTHETICAL | POLYMORPHIC_SIGNATURE |
(spMethod != null ?
spMethod.flags() & Flags.AccessFlags :
......
......@@ -2153,9 +2153,6 @@ public class Gen extends JCTree.Visitor {
}
result = items.
makeImmediateItem(sym.type, ((VarSymbol) sym).getConstValue());
} else if (allowInvokedynamic && sym.kind == MTH && ssym == syms.invokeDynamicType.tsym) {
base.drop();
result = items.makeDynamicItem(sym);
} else {
if (!accessSuper)
sym = binaryQualifier(sym, tree.selected.type);
......
......@@ -139,13 +139,6 @@ public class Items {
return new StaticItem(member);
}
/** Make an item representing a dynamically invoked method.
* @param member The represented symbol.
*/
Item makeDynamicItem(Symbol member) {
return new DynamicItem(member);
}
/** Make an item representing an instance variable or method.
* @param member The represented symbol.
* @param nonvirtual Is the reference not virtual? (true for constructors
......@@ -464,38 +457,6 @@ public class Items {
}
}
/** An item representing a dynamic call site.
*/
class DynamicItem extends StaticItem {
DynamicItem(Symbol member) {
super(member);
Assert.check(member.owner == syms.invokeDynamicType.tsym);
}
Item load() {
Assert.error();
return null;
}
void store() {
Assert.error();
}
Item invoke() {
// assert target.hasNativeInvokeDynamic();
MethodType mtype = (MethodType)member.erasure(types);
int rescode = Code.typecode(mtype.restype);
ClassFile.NameAndType descr = new ClassFile.NameAndType(member.name, mtype);
code.emitInvokedynamic(pool.put(descr), mtype);
return stackItem[rescode];
}
public String toString() {
return "dynamic(" + member + ")";
}
}
/** An item representing an instance variable or method.
*/
class MemberItem extends Item {
......
......@@ -284,13 +284,6 @@ public class Main {
}
}
// phase this out with JSR 292 PFD
if ("no".equals(options.get("allowTransitionalJSR292"))) {
options.put("allowTransitionalJSR292", null);
} else if (target.hasInvokedynamic() && options.isUnset("allowTransitionalJSR292")) {
options.put("allowTransitionalJSR292", "allowTransitionalJSR292");
}
// handle this here so it works even if no other options given
String showClass = options.get("showClass");
if (showClass != null) {
......
......@@ -128,8 +128,6 @@ compiler.err.call.to.super.not.allowed.in.enum.ctor=\
compiler.err.no.superclass=\
{0} has no superclass
compiler.warn.type.parameter.on.polymorphic.signature=\
change obsolete notation for MethodHandle invocations from x.<T>invoke(y) to (T)x.invoke(y)
compiler.warn.wrong.target.for.polymorphic.signature.definition=\
MethodHandle API building requires -target 7 runtimes or better; current is -target {0}
......
......@@ -74,7 +74,6 @@ public class Names {
public final Name serialVersionUID;
public final Name java_lang_Enum;
public final Name java_dyn_MethodHandle;
public final Name java_dyn_InvokeDynamic;
public final Name package_info;
public final Name ConstantValue;
public final Name LineNumberTable;
......@@ -115,7 +114,6 @@ public class Names {
public final Name value;
public final Name getMessage;
public final Name getClass;
public final Name invoke; //allowTransitionalJSR292 only
public final Name TYPE;
public final Name TYPE_USE;
public final Name TYPE_PARAMETER;
......@@ -186,7 +184,6 @@ public class Names {
java_io_Serializable = fromString("java.io.Serializable");
java_lang_Enum = fromString("java.lang.Enum");
java_dyn_MethodHandle = fromString("java.dyn.MethodHandle");
java_dyn_InvokeDynamic = fromString("java.dyn.InvokeDynamic");
package_info = fromString("package-info");
serialVersionUID = fromString("serialVersionUID");
ConstantValue = fromString("ConstantValue");
......@@ -230,7 +227,6 @@ public class Names {
value = fromString("value");
getMessage = fromString("getMessage");
getClass = fromString("getClass");
invoke = fromString("invoke"); //allowTransitionalJSR292 only
TYPE = fromString("TYPE");
TYPE_USE = fromString("TYPE_USE");
......
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* 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.
*
* 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.
*/
// key: compiler.warn.type.parameter.on.polymorphic.signature
// key: compiler.err.unreported.exception.need.to.catch.or.throw
import java.dyn.MethodHandle;
class TypeParameterOnPolymorphicSignature {
void test(MethodHandle mh) {
mh.<void>invokeExact("",123);
}
}
InvokeDynTrans.java:55:39: compiler.warn.type.parameter.on.polymorphic.signature
InvokeDynTrans.java:57:34: compiler.warn.type.parameter.on.polymorphic.signature
- compiler.err.warnings.and.werror
1 error
2 warnings
/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* 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.
*
* 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.
*/
/*
* @test
* @bug 6754038 6979327
* @summary Generate call sites for method handle
* @author jrose
*
* @compile/fail/ref=InvokeMHTrans.out -Werror -XDrawDiagnostics -source 7 -target 7 InvokeMHTrans.java
*/
/*
* Standalone testing:
* <code>
* $ cd $MY_REPO_DIR/langtools
* $ (cd make; make)
* $ ./dist/bootstrap/bin/javac -d dist test/tools/javac/meth/InvokeMH.java
* $ javap -c -classpath dist meth.InvokeMH
* </code>
*/
package meth;
import java.dyn.MethodHandle;
public class InvokeMHTrans {
void test(MethodHandle mh_SiO,
MethodHandle mh_vS,
MethodHandle mh_vi,
MethodHandle mh_vv) throws Throwable {
Object o; String s; int i; // for return type testing
// next five must have sig = (String,int)Object
mh_SiO.invokeExact("world", 123);
mh_SiO.invokeExact("mundus", 456);
Object k = "kosmos";
mh_SiO.invokeExact((String)k, 789);
o = mh_SiO.invokeExact((String)null, 000);
o = mh_SiO.<Object>invokeExact("arda", -123);
// sig = ()String
s = mh_vS.<String>invokeExact();
// sig = ()int
i = mh_vi.<int>invokeExact();
o = mh_vi.<int>invokeExact();
//s = mh_vi.<int>invokeExact(); //BAD
mh_vi.<int>invokeExact();
// sig = ()void
//o = mh_vv.<void>invokeExact(); //BAD
mh_vv.<void>invokeExact();
}
void testGen(MethodHandle mh_SiO,
MethodHandle mh_vS,
MethodHandle mh_vi,
MethodHandle mh_vv) throws Throwable {
Object o; String s; int i; // for return type testing
// next five must have sig = (*,*)*
mh_SiO.invokeGeneric((Object)"world", (Object)123);
mh_SiO.<void>invokeGeneric((Object)"mundus", (Object)456);
Object k = "kosmos";
mh_SiO.invokeGeneric(k, 789);
o = mh_SiO.invokeGeneric(null, 000);
o = mh_SiO.<Object>invokeGeneric("arda", -123);
// sig = ()String
o = mh_vS.invokeGeneric();
// sig = ()int
i = mh_vi.<int>invokeGeneric();
o = mh_vi.invokeGeneric();
//s = mh_vi.<int>invokeGeneric(); //BAD
mh_vi.<void>invokeGeneric();
// sig = ()void
//o = mh_vv.<void>invokeGeneric(); //BAD
o = mh_vv.invokeGeneric();
}
}
InvokeMHTrans.java:59:39: compiler.warn.type.parameter.on.polymorphic.signature
InvokeMHTrans.java:62:38: compiler.warn.type.parameter.on.polymorphic.signature
InvokeMHTrans.java:65:35: compiler.warn.type.parameter.on.polymorphic.signature
InvokeMHTrans.java:66:35: compiler.warn.type.parameter.on.polymorphic.signature
InvokeMHTrans.java:68:31: compiler.warn.type.parameter.on.polymorphic.signature
InvokeMHTrans.java:72:32: compiler.warn.type.parameter.on.polymorphic.signature
InvokeMHTrans.java:83:35: compiler.warn.type.parameter.on.polymorphic.signature
InvokeMHTrans.java:87:41: compiler.warn.type.parameter.on.polymorphic.signature
InvokeMHTrans.java:93:37: compiler.warn.type.parameter.on.polymorphic.signature
InvokeMHTrans.java:96:34: compiler.warn.type.parameter.on.polymorphic.signature
- compiler.err.warnings.and.werror
1 error
10 warnings
......@@ -42,13 +42,15 @@ public class TestCP {
static class TestClass {
void test(MethodHandle mh) throws Throwable {
Number n = mh.<Number>invokeExact("daddy",1,'n');
Number n = (Number)mh.invokeExact("daddy",1,'n');
n = (Number)mh.invokeExact("bunny",1,'d');
n = (Number)(mh.invokeExact("foo",1,'d'));
n = (Number)((mh.invokeExact("bar",1,'d')));
}
}
static final String PS_TYPE = "(Ljava/lang/String;IC)Ljava/lang/Number;";
static final int PS_CALLS_COUNT = 2;
static final int PS_CALLS_COUNT = 4;
static final String SUBTEST_NAME = TestClass.class.getName() + ".class";
static final String TEST_METHOD_NAME = "test";
......
......@@ -35,6 +35,19 @@ import java.dyn.*;
class XlintWarn {
void test(MethodHandle mh) throws Throwable {
int i1 = (int)mh.invokeExact();
int i2 = (int)mh.invokeVarargs();
int i2 = (int)mh.invokeGeneric();
int i3 = (int)mh.invokeWithArguments();
}
void test2(MethodHandle mh) throws Throwable {
int i1 = (int)(mh.invokeExact());
int i2 = (int)(mh.invokeGeneric());
int i3 = (int)(mh.invokeWithArguments());
}
void test3(MethodHandle mh) throws Throwable {
int i1 = (int)((mh.invokeExact()));
int i2 = (int)((mh.invokeGeneric()));
int i3 = (int)((mh.invokeWithArguments()));
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册