# HG changeset patch # User jrose # Date 1276899124 25200 # Node ID 005bec70ca27239bdd4e6169b9b078507401aa72 # Parent ab1356297c674940d38534ae6a0b4bdaf567cc14# Parent 2a28dcbef3a7a04eda75eea57636379b91fbd03c Merge diff -r ab1356297c67 -r 005bec70ca27 src/share/classes/com/sun/tools/javac/code/Flags.java --- a/src/share/classes/com/sun/tools/javac/code/Flags.java Thu Jun 17 16:28:21 2010 -0700 +++ b/src/share/classes/com/sun/tools/javac/code/Flags.java Fri Jun 18 15:12:04 2010 -0700 @@ -235,6 +235,12 @@ */ public static final long DISJOINT = 1L<<39; + /** + * Flag that marks a signature-polymorphic invoke method. + * (These occur inside java.dyn.MethodHandle.) + */ + public static final long POLYMORPHIC_SIGNATURE = 1L<<40; + /** Modifier masks. */ public static final int diff -r ab1356297c67 -r 005bec70ca27 src/share/classes/com/sun/tools/javac/code/Source.java --- a/src/share/classes/com/sun/tools/javac/code/Source.java Thu Jun 17 16:28:21 2010 -0700 +++ b/src/share/classes/com/sun/tools/javac/code/Source.java Fri Jun 18 15:12:04 2010 -0700 @@ -171,6 +171,10 @@ public boolean allowStringsInSwitch() { return compareTo(JDK1_7) >= 0; } + // JSR 292: recognize @PolymorphicSignature on java/dyn names + public boolean allowPolymorphicSignature() { + return compareTo(JDK1_7) >= 0; + } public static SourceVersion toSourceVersion(Source source) { switch(source) { case JDK1_2: diff -r ab1356297c67 -r 005bec70ca27 src/share/classes/com/sun/tools/javac/code/Symtab.java --- a/src/share/classes/com/sun/tools/javac/code/Symtab.java Thu Jun 17 16:28:21 2010 -0700 +++ b/src/share/classes/com/sun/tools/javac/code/Symtab.java Fri Jun 18 15:12:04 2010 -0700 @@ -120,6 +120,7 @@ public final Type cloneableType; public final Type serializableType; public final Type methodHandleType; + public final Type polymorphicSignatureType; public final Type invokeDynamicType; public final Type throwableType; public final Type errorType; @@ -291,24 +292,6 @@ } } - public void synthesizeMHTypeIfMissing(final Type type) { - final Completer completer = type.tsym.completer; - if (completer != null) { - type.tsym.completer = new Completer() { - public void complete(Symbol sym) throws CompletionFailure { - try { - completer.complete(sym); - } catch (CompletionFailure e) { - sym.flags_field |= (PUBLIC | ABSTRACT); - ((ClassType) sym.type).supertype_field = objectType; - // do not bother to create MH.type if not visibly declared - // this sym just accumulates invoke(...) methods - } - } - }; - } - } - public void synthesizeBoxTypeIfMissing(final Type type) { ClassSymbol sym = reader.enterClass(boxedName[type.tag]); final Completer completer = sym.completer; @@ -426,6 +409,7 @@ throwableType = enterClass("java.lang.Throwable"); 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"); @@ -463,8 +447,7 @@ synthesizeEmptyInterfaceIfMissing(cloneableType); synthesizeEmptyInterfaceIfMissing(serializableType); - synthesizeMHTypeIfMissing(methodHandleType); - synthesizeMHTypeIfMissing(invokeDynamicType); + synthesizeEmptyInterfaceIfMissing(polymorphicSignatureType); synthesizeBoxTypeIfMissing(doubleType); synthesizeBoxTypeIfMissing(floatType); synthesizeBoxTypeIfMissing(voidType); diff -r ab1356297c67 -r 005bec70ca27 src/share/classes/com/sun/tools/javac/comp/Attr.java --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Thu Jun 17 16:28:21 2010 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri Jun 18 15:12:04 2010 -0700 @@ -122,7 +122,6 @@ relax = (options.get("-retrofit") != null || options.get("-relax") != null); useBeforeDeclarationWarning = options.get("useBeforeDeclarationWarning") != null; - allowInvokedynamic = options.get("invokedynamic") != null; enableSunApiLintControl = options.get("enableSunApiLintControl") != null; } @@ -155,10 +154,6 @@ */ boolean allowAnonOuterThis; - /** Switch: allow invokedynamic syntax - */ - boolean allowInvokedynamic; - /** * Switch: warn about use of variable before declaration? * RFE: 6425594 @@ -1384,9 +1379,15 @@ // as a special case, MethodHandle.invoke(abc) and InvokeDynamic.foo(abc) // has type , and T can be a primitive type. if (tree.meth.getTag() == JCTree.SELECT && !typeargtypes.isEmpty()) { - Type selt = ((JCFieldAccess) tree.meth).selected.type; - if ((selt == syms.methodHandleType && methName == names.invoke) || selt == syms.invokeDynamicType) { + JCFieldAccess mfield = (JCFieldAccess) tree.meth; + if ((mfield.selected.type.tsym != null && + (mfield.selected.type.tsym.flags() & POLYMORPHIC_SIGNATURE) != 0) + || + (mfield.sym != null && + (mfield.sym.flags() & POLYMORPHIC_SIGNATURE) != 0)) { assert types.isSameType(restype, typeargtypes.head) : mtype; + assert mfield.selected.type == syms.methodHandleType + || mfield.selected.type == syms.invokeDynamicType; typeargtypesNonRefOK = true; } } diff -r ab1356297c67 -r 005bec70ca27 src/share/classes/com/sun/tools/javac/comp/MemberEnter.java --- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Thu Jun 17 16:28:21 2010 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Fri Jun 18 15:12:04 2010 -0700 @@ -768,6 +768,12 @@ && s.owner.kind != MTH && types.isSameType(c.type, syms.deprecatedType)) s.flags_field |= Flags.DEPRECATED; + // Internally to java.dyn, a @PolymorphicSignature annotation + // translates to a classfile attribute. + if (!c.type.isErroneous() + && types.isSameType(c.type, syms.polymorphicSignatureType)) { + s.flags_field |= Flags.POLYMORPHIC_SIGNATURE; + } if (!annotated.add(a.type.tsym)) log.error(a.pos, "duplicate.annotation"); } diff -r ab1356297c67 -r 005bec70ca27 src/share/classes/com/sun/tools/javac/comp/Resolve.java --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java Thu Jun 17 16:28:21 2010 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Jun 18 15:12:04 2010 -0700 @@ -67,7 +67,7 @@ JCDiagnostic.Factory diags; public final boolean boxingEnabled; // = source.allowBoxing(); public final boolean varargsEnabled; // = source.allowVarargs(); - public final boolean allowInvokedynamic; // = options.get("invokedynamic"); + public final boolean allowPolymorphicSignature; private final boolean debugResolve; public static Resolve instance(Context context) { @@ -105,7 +105,7 @@ varargsEnabled = source.allowVarargs(); Options options = Options.instance(context); debugResolve = options.get("debugresolve") != null; - allowInvokedynamic = options.get("invokedynamic") != null; + allowPolymorphicSignature = source.allowPolymorphicSignature() || options.get("invokedynamic") != null; } /** error symbols, which are returned when resolution fails @@ -301,6 +301,7 @@ boolean useVarargs, Warner warn) throws Infer.InferenceException { + assert ((m.flags() & (POLYMORPHIC_SIGNATURE|HYPOTHETICAL)) != POLYMORPHIC_SIGNATURE); if (useVarargs && (m.flags() & VARARGS) == 0) return null; Type mt = types.memberType(site, m); @@ -576,6 +577,14 @@ if (sym.kind == ERR) return bestSoFar; if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar; assert sym.kind < AMBIGUOUS; + if ((sym.flags() & POLYMORPHIC_SIGNATURE) != 0 && allowPolymorphicSignature) { + assert(site.tag == CLASS); + // Never match a MethodHandle.invoke directly. + if (useVarargs | allowBoxing | operator) + return bestSoFar; + // Supply an exactly-typed implicit method instead. + sym = findPolymorphicSignatureInstance(env, sym.owner.type, sym.name, (MethodSymbol) sym, argtypes, typeargtypes); + } try { if (rawInstantiate(env, site, sym, argtypes, typeargtypes, allowBoxing, useVarargs, Warner.noWarnings) == null) { @@ -746,6 +755,14 @@ boolean allowBoxing, boolean useVarargs, boolean operator) { + Symbol bestSoFar = methodNotFound; + if ((site.tsym.flags() & POLYMORPHIC_SIGNATURE) != 0 && + allowPolymorphicSignature && + site.tag == CLASS && + !(useVarargs | allowBoxing | operator)) { + // supply an exactly-typed implicit method in java.dyn.InvokeDynamic + bestSoFar = findPolymorphicSignatureInstance(env, site, name, null, argtypes, typeargtypes); + } return findMethod(env, site, name, @@ -753,7 +770,7 @@ typeargtypes, site.tsym.type, true, - methodNotFound, + bestSoFar, allowBoxing, useVarargs, operator); @@ -897,13 +914,14 @@ * @param argtypes The method's value arguments. * @param typeargtypes The method's type arguments */ - Symbol findImplicitMethod(Env env, - Type site, - Name name, - List argtypes, - List typeargtypes) { - assert allowInvokedynamic; - assert site == syms.invokeDynamicType || (site == syms.methodHandleType && name == names.invoke); + Symbol findPolymorphicSignatureInstance(Env env, + Type site, + Name name, + MethodSymbol spMethod, // sig. poly. method or null if none + List argtypes, + List typeargtypes) { + assert allowPolymorphicSignature; + //assert site == syms.invokeDynamicType || site == syms.methodHandleType : site; ClassSymbol c = (ClassSymbol) site.tsym; Scope implicit = c.members().next; if (implicit == null) { @@ -918,12 +936,22 @@ return methodNotFound; } List paramtypes = Type.map(argtypes, implicitArgType); + long flags; + List exType; + if (spMethod != null) { + exType = spMethod.getThrownTypes(); + flags = spMethod.flags() & AccessFlags; + } else { + // make it throw all exceptions + //assert(site == syms.invokeDynamicType); + exType = List.of(syms.throwableType); + flags = PUBLIC | STATIC; + } MethodType mtype = new MethodType(paramtypes, restype, - List.nil(), + exType, syms.methodClass); - int flags = PUBLIC | ABSTRACT; - if (site == syms.invokeDynamicType) flags |= STATIC; + flags |= ABSTRACT | HYPOTHETICAL | POLYMORPHIC_SIGNATURE; Symbol m = null; for (Scope.Entry e = implicit.lookup(name); e.scope != null; @@ -1338,14 +1366,6 @@ methodResolutionCache.put(steps.head, sym); steps = steps.tail; } - if (sym.kind >= AMBIGUOUS && - allowInvokedynamic && - (site == syms.invokeDynamicType || - site == syms.methodHandleType && name == names.invoke)) { - // lookup failed; supply an exactly-typed implicit method - sym = findImplicitMethod(env, site, name, argtypes, typeargtypes); - env.info.varArgs = false; - } if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error MethodResolutionPhase errPhase = firstErroneousResolutionPhase(); diff -r ab1356297c67 -r 005bec70ca27 src/share/classes/com/sun/tools/javac/jvm/ClassReader.java --- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Thu Jun 17 16:28:21 2010 -0700 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Fri Jun 18 15:12:04 2010 -0700 @@ -1098,6 +1098,12 @@ } }, + new AttributeReader(names.PolymorphicSignature, V45_3/*S.B.V51*/, CLASS_OR_MEMBER_ATTRIBUTE) { + void read(Symbol sym, int attrLen) { + sym.flags_field |= POLYMORPHIC_SIGNATURE; + } + }, + // The following attributes for a Code attribute are not currently handled // StackMapTable diff -r ab1356297c67 -r 005bec70ca27 src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java --- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Thu Jun 17 16:28:21 2010 -0700 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Fri Jun 18 15:12:04 2010 -0700 @@ -651,6 +651,13 @@ endAttr(alenIdx); acount++; } + if ((flags & POLYMORPHIC_SIGNATURE) != 0) { + if (target.majorVersion < 51) + throw new AssertionError("PolymorphicSignature attributes in java/dyn must be written with -target 7 (required major version is 51, current is"+target.majorVersion+")"); + int alenIdx = writeAttr(names.PolymorphicSignature); + endAttr(alenIdx); + acount++; + } return acount; } diff -r ab1356297c67 -r 005bec70ca27 src/share/classes/com/sun/tools/javac/jvm/Gen.java --- a/src/share/classes/com/sun/tools/javac/jvm/Gen.java Thu Jun 17 16:28:21 2010 -0700 +++ b/src/share/classes/com/sun/tools/javac/jvm/Gen.java Fri Jun 18 15:12:04 2010 -0700 @@ -121,7 +121,7 @@ : options.get("-g:vars") != null; genCrt = options.get("-Xjcov") != null; debugCode = options.get("debugcode") != null; - allowInvokedynamic = options.get("invokedynamic") != null; + allowInvokedynamic = target.hasInvokedynamic() || options.get("invokedynamic") != null; generateIproxies = target.requiresIproxy() || diff -r ab1356297c67 -r 005bec70ca27 src/share/classes/com/sun/tools/javac/main/Main.java --- a/src/share/classes/com/sun/tools/javac/main/Main.java Thu Jun 17 16:28:21 2010 -0700 +++ b/src/share/classes/com/sun/tools/javac/main/Main.java Fri Jun 18 15:12:04 2010 -0700 @@ -281,9 +281,6 @@ } } } - if (target.hasInvokedynamic()) { - options.put("invokedynamic", "invokedynamic"); - } // handle this here so it works even if no other options given String showClass = options.get("showClass"); diff -r ab1356297c67 -r 005bec70ca27 src/share/classes/com/sun/tools/javac/util/Names.java --- a/src/share/classes/com/sun/tools/javac/util/Names.java Thu Jun 17 16:28:21 2010 -0700 +++ b/src/share/classes/com/sun/tools/javac/util/Names.java Fri Jun 18 15:12:04 2010 -0700 @@ -103,6 +103,7 @@ public final Name RuntimeInvisibleTypeAnnotations; public final Name RuntimeVisibleParameterAnnotations; public final Name RuntimeInvisibleParameterAnnotations; + public final Name PolymorphicSignature; public final Name Value; public final Name EnclosingMethod; public final Name desiredAssertionStatus; @@ -115,7 +116,6 @@ public final Name value; public final Name getMessage; public final Name getClass; - public final Name invoke; public final Name TYPE; public final Name TYPE_USE; public final Name TYPE_PARAMETER; @@ -213,6 +213,7 @@ RuntimeInvisibleTypeAnnotations = fromString("RuntimeInvisibleTypeAnnotations"); RuntimeVisibleParameterAnnotations = fromString("RuntimeVisibleParameterAnnotations"); RuntimeInvisibleParameterAnnotations = fromString("RuntimeInvisibleParameterAnnotations"); + PolymorphicSignature = fromString("PolymorphicSignature"); Value = fromString("Value"); EnclosingMethod = fromString("EnclosingMethod"); @@ -227,7 +228,6 @@ value = fromString("value"); getMessage = fromString("getMessage"); getClass = fromString("getClass"); - invoke = fromString("invoke"); TYPE = fromString("TYPE"); TYPE_USE = fromString("TYPE_USE"); diff -r ab1356297c67 -r 005bec70ca27 test/tools/javac/meth/InvokeDyn.java --- a/test/tools/javac/meth/InvokeDyn.java Thu Jun 17 16:28:21 2010 -0700 +++ b/test/tools/javac/meth/InvokeDyn.java Fri Jun 18 15:12:04 2010 -0700 @@ -47,7 +47,7 @@ import java.dyn.InvokeDynamic; public class InvokeDyn { - void test() { + void test() throws Throwable { Object x = "hello"; InvokeDynamic.greet(x, "world", 123); InvokeDynamic.greet(x, "mundus", 456); diff -r ab1356297c67 -r 005bec70ca27 test/tools/javac/meth/InvokeMH.java --- a/test/tools/javac/meth/InvokeMH.java Thu Jun 17 16:28:21 2010 -0700 +++ b/test/tools/javac/meth/InvokeMH.java Fri Jun 18 15:12:04 2010 -0700 @@ -48,28 +48,56 @@ void test(MethodHandle mh_SiO, MethodHandle mh_vS, MethodHandle mh_vi, - MethodHandle mh_vv) { + 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.invoke("world", 123); - mh_SiO.invoke("mundus", 456); + mh_SiO.invokeExact("world", 123); + mh_SiO.invokeExact("mundus", 456); Object k = "kosmos"; - mh_SiO.invoke((String)k, 789); - o = mh_SiO.invoke((String)null, 000); - o = mh_SiO.invoke("arda", -123); + mh_SiO.invokeExact((String)k, 789); + o = mh_SiO.invokeExact((String)null, 000); + o = mh_SiO.invokeExact("arda", -123); // sig = ()String - s = mh_vS.invoke(); + s = mh_vS.invokeExact(); // sig = ()int - i = mh_vi.invoke(); - o = mh_vi.invoke(); - //s = mh_vi.invoke(); //BAD - mh_vi.invoke(); + i = mh_vi.invokeExact(); + o = mh_vi.invokeExact(); + //s = mh_vi.invokeExact(); //BAD + mh_vi.invokeExact(); // sig = ()void - //o = mh_vv.invoke(); //BAD - mh_vv.invoke(); + //o = mh_vv.invokeExact(); //BAD + mh_vv.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.invokeGeneric((Object)"mundus", (Object)456); + Object k = "kosmos"; + mh_SiO.invokeGeneric(k, 789); + o = mh_SiO.invokeGeneric(null, 000); + o = mh_SiO.invokeGeneric("arda", -123); + + // sig = ()String + o = mh_vS.invokeGeneric(); + + // sig = ()int + i = mh_vi.invokeGeneric(); + o = mh_vi.invokeGeneric(); + //s = mh_vi.invokeGeneric(); //BAD + mh_vi.invokeGeneric(); + + // sig = ()void + //o = mh_vv.invokeGeneric(); //BAD + o = mh_vv.invokeGeneric(); } }