changeset 69:76d6efbc30a4

meth-edrfix: assign bug numbers; also rebase
author jrose
date Wed, 25 Aug 2010 22:18:45 -0700
parents 49cabfbbb3da
children b733d7c4526e
files meth-edrfix-6979327.patch meth-edrfix.patch series
diffstat 3 files changed, 434 insertions(+), 431 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/meth-edrfix-6979327.patch	Wed Aug 25 22:18:45 2010 -0700
@@ -0,0 +1,427 @@
+6979327: method handle invocation should use casts instead of type parameters to specify return type
+Summary: Use cast-based target typing instead of type parameter syntax to specify types of method handle calls.
+Reviewed-by: ?
+
+Allow new versions of javac to compile old versions of JSR 292 code.
+Allow new versions of the JSR 292 code to omit type parameters from polymorphic signatures.
+Instead, casts will perform the same function, with a clearer meaning and cleaner syntax.
+When the old versions of JSR 292 code have gone away, we will kill the flag 'allowTransitionalJSR292'.
+
+Local definitions:
+ "new version of javac" = version which requires @PolymorphicSignature annotations in java.dyn.MethodHandle.
+ "old version of JSR 292 code" = version in which java.dyn.MethodHandle lacks @PolymorphicSignature annotations or uses type parameters.
+
+diff --git a/src/share/classes/com/sun/tools/javac/code/Source.java b/src/share/classes/com/sun/tools/javac/code/Source.java
+--- a/src/share/classes/com/sun/tools/javac/code/Source.java
++++ b/src/share/classes/com/sun/tools/javac/code/Source.java
+@@ -171,10 +171,6 @@
+     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 --git a/src/share/classes/com/sun/tools/javac/comp/Attr.java b/src/share/classes/com/sun/tools/javac/comp/Attr.java
+--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java
++++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java
+@@ -1121,6 +1121,7 @@
+ 
+     public void visitExec(JCExpressionStatement tree) {
+         attribExpr(tree.expr, env);
++        tree.expr = pushTargetType(syms.voidType, tree.expr);
+         result = null;
+     }
+ 
+@@ -1378,23 +1379,22 @@
+                               restype.tsym);
+             }
+ 
+-            // as a special case, MethodHandle.<T>invoke(abc) and InvokeDynamic.<T>foo(abc)
+-            // has type <T>, and T can be a primitive type.
+-            if (tree.meth.getTag() == JCTree.SELECT && !typeargtypes.isEmpty()) {
+-              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;
+-              }
++            // 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.selected.type.tsym == syms.invokeDynamicType.tsym && rs.recognizeInvokeDynamic) {
++                    typeargtypesNonRefOK = true;
++                } else if (mfield.selected.type.tsym == syms.methodHandleType.tsym && rs.recognizeMethodHandles) {
++                    if (mfield.sym != null && rs.isPolymorphicSignatureInstance(mfield.sym))
++                        typeargtypesNonRefOK = true;  // invokeExact, invokeGeneric
++                    else if (methName == names.invoke)
++                        typeargtypesNonRefOK = true;  // older logic that doesn't use annotations
++                }
+             }
+ 
+-            if (!typeargtypesNonRefOK) {
++            if (!(rs.allowTransitionalJSR292 && typeargtypesNonRefOK)) {
+                 chk.checkRefTypes(tree.typeargs, typeargtypes);
+             }
+ 
+@@ -1949,12 +1949,48 @@
+         Type clazztype = attribType(tree.clazz, env);
+         chk.validate(tree.clazz, env);
+         Type exprtype = attribExpr(tree.expr, env, Infer.anyPoly);
++        tree.expr = pushTargetType(clazztype, tree.expr);
+         Type owntype = chk.checkCastable(tree.expr.pos(), exprtype, clazztype);
+         if (exprtype.constValue() != null)
+             owntype = cfolder.coerce(exprtype, owntype);
+         result = check(tree, capture(owntype), VAL, pkind, pt);
+     }
+ 
++    // A cast or occurrence as an expression statement can affect the linkage of some method calls.
++    JCExpression pushTargetType(Type targetType, JCExpression expr) {
++        // JSR 292:  Link some calls according to return type as indicated by a cast.
++        JCExpression transformedExpr = expr;
++        JCTypeCast enclosingCast = null;
++        if (targetType.isPrimitive() && expr.getTag() == JCTree.TYPECAST) {
++            enclosingCast = (JCTypeCast)expr;
++            if (types.boxedClass(targetType) == enclosingCast.type.tsym) {
++                expr = enclosingCast.expr;
++                // If the expr in turn is a MH.invoke expression,
++                // we will change (int)(Integer)MH.invoke(...) to (int)MH.invoke(...),
++                // with a linkage change to return the int directly.
++            }
++        }
++        if (expr.getTag() == JCTree.APPLY) {
++            JCExpression meth = ((JCMethodInvocation)expr).meth;
++            if (meth.getTag() == JCTree.SELECT) {
++                JCFieldAccess methsel = (JCFieldAccess)meth;
++                if (rs.isPolymorphicSignatureInstance(methsel.sym)) {
++                    MethodSymbol sym = (MethodSymbol) methsel.sym;
++                    MethodType oldType = sym.type.asMethodType();
++                    Symbol newSym = rs.findPolymorphicSignatureInstance(sym.owner.type, sym.name, sym,
++                                                                        targetType,
++                                                                        oldType.argtypes);
++                    if (!rs.isPolymorphicSignatureInstance(newSym))
++                        throw new AssertionError("can't split poly sym: "+sym);
++                    methsel.sym = newSym;
++                    expr.type = targetType;
++                    transformedExpr = expr;
++                }
++            }
++        }
++        return transformedExpr;
++    }
++
+     public void visitTypeTest(JCInstanceOf tree) {
+         Type exprtype = chk.checkNullOrRefType(
+             tree.expr.pos(), attribExpr(tree.expr, env));
+diff --git a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
+--- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
++++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
+@@ -772,8 +772,14 @@
+             // translates to a classfile attribute.
+             if (!c.type.isErroneous()
+                 && types.isSameType(c.type, syms.polymorphicSignatureType)) {
++                if (!target.hasMethodHandles()) {
++                    // Somebody is compiling JDK7 source code to a JDK6 target.
++                    // Make it a strict warning, since it is unlikely but important.
++                    log.strictWarning(env.tree.pos(), "wrong.target.for.polymorphic.signature.definition", target.name);
++                }
++                // Pull the flag through for better diagnostics, even on a bad target.
+                 s.flags_field |= Flags.POLYMORPHIC_SIGNATURE;
+-            }
++              }
+             if (!annotated.add(a.type.tsym))
+                 log.error(a.pos, "duplicate.annotation");
+         }
+diff --git a/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/src/share/classes/com/sun/tools/javac/comp/Resolve.java
+--- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java
++++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java
+@@ -67,7 +67,9 @@
+     JCDiagnostic.Factory diags;
+     public final boolean boxingEnabled; // = source.allowBoxing();
+     public final boolean varargsEnabled; // = source.allowVarargs();
+-    public final boolean allowPolymorphicSignature;
++    public final boolean recognizeMethodHandles;
++    public final boolean recognizeInvokeDynamic;
++    public final boolean allowTransitionalJSR292;
+     private final boolean debugResolve;
+ 
+     public static Resolve instance(Context context) {
+@@ -105,7 +107,10 @@
+         varargsEnabled = source.allowVarargs();
+         Options options = Options.instance(context);
+         debugResolve = options.get("debugresolve") != null;
+-        allowPolymorphicSignature = source.allowPolymorphicSignature() || options.get("invokedynamic") != null;
++        allowTransitionalJSR292 = options.get("allowTransitionalJSR292") != null;
++        Target target = Target.instance(context);
++        recognizeMethodHandles = allowTransitionalJSR292 || target.hasMethodHandles();
++        recognizeInvokeDynamic = allowTransitionalJSR292 || target.hasInvokedynamic() && options.get("invokedynamic") != null;
+     }
+ 
+     /** error symbols, which are returned when resolution fails
+@@ -301,7 +306,6 @@
+                         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);
+ 
+@@ -578,13 +582,15 @@
+         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) {
++        if (isPolymorphicSignatureGeneric(sym) && recognizeMethodHandles) {
+             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);
++            Type restype = initialPolymorphicSignatureResultType(env, typeargtypes);
++            sym = findPolymorphicSignatureInstance(sym.owner.type, sym.name, (MethodSymbol) sym, restype, argtypes);
++            assert null != instantiate(env, site, sym, argtypes, typeargtypes, false, false, Warner.noWarnings);
+         }
+         try {
+             if (rawInstantiate(env, site, sym, argtypes, typeargtypes,
+@@ -757,12 +763,13 @@
+                       boolean useVarargs,
+                       boolean operator) {
+         Symbol bestSoFar = methodNotFound;
+-        if ((site.tsym.flags() & POLYMORPHIC_SIGNATURE) != 0 &&
+-            allowPolymorphicSignature &&
++        if (isPolymorphicSignatureGeneric(site.tsym) && recognizeInvokeDynamic &&
+             site.tag == CLASS &&
+             !(useVarargs | allowBoxing | operator)) {
+             // supply an exactly-typed implicit method in java.dyn.InvokeDynamic
+-            bestSoFar = findPolymorphicSignatureInstance(env, site, name, null, argtypes, typeargtypes);
++            Type restype = initialPolymorphicSignatureResultType(env, typeargtypes);
++            bestSoFar = findPolymorphicSignatureInstance(site, name, null, restype, argtypes);
++            assert null != instantiate(env, site, bestSoFar, argtypes, typeargtypes, false, false, Warner.noWarnings);
+         }
+         return findMethod(env,
+                           site,
+@@ -908,43 +915,35 @@
+     /** Find or create an implicit method of exactly the given type (after erasure).
+      *  Searches in a side table, not the main scope of the site.
+      *  This emulates the lookup process required by JSR 292 in JVM.
+-     *  @param env       The current environment.
+-     *  @param site      The original type from where the selection
+-     *                   takes place.
++     *  @param site      The original type from where the selection takes place.
+      *  @param name      The method's name.
+-     *  @param argtypes  The method's value arguments.
+-     *  @param typeargtypes The method's type arguments
++     *  @param spMethod  A template for the implicit method, or null.
++     *  @param restype   The required return type.
++     *  @param argtypes  The required argument types.
+      */
+-    Symbol findPolymorphicSignatureInstance(Env<AttrContext> env,
+-                                            Type site,
++    Symbol findPolymorphicSignatureInstance(Type site,
+                                             Name name,
+                                             MethodSymbol spMethod,  // sig. poly. method or null if none
+-                                            List<Type> argtypes,
+-                                            List<Type> typeargtypes) {
+-        assert allowPolymorphicSignature;
++                                            Type restype,
++                                            List<Type> argtypes) {
++        assert (recognizeMethodHandles || recognizeInvokeDynamic);
+         //assert site == syms.invokeDynamicType || site == syms.methodHandleType : site;
+         ClassSymbol c = (ClassSymbol) site.tsym;
+         Scope implicit = c.members().next;
+         if (implicit == null) {
+             c.members().next = implicit = new Scope(c);
+         }
+-        Type restype;
+-        if (typeargtypes.isEmpty()) {
+-            restype = syms.objectType;
+-        } else {
+-            restype = typeargtypes.head;
+-            if (!typeargtypes.tail.isEmpty())
+-                return methodNotFound;
+-        }
+         List<Type> paramtypes = Type.map(argtypes, implicitArgType);
+         long flags;
+         List<Type> exType;
+         if (spMethod != null) {
++            assert spMethod.owner == site.tsym;
+             exType = spMethod.getThrownTypes();
+             flags = spMethod.flags() & AccessFlags;
+         } else {
+             // make it throw all exceptions
+-            //assert(site == syms.invokeDynamicType);
++            assert recognizeInvokeDynamic;
++            assert site == syms.invokeDynamicType;
+             exType = List.of(syms.throwableType);
+             flags = PUBLIC | STATIC;
+         }
+@@ -972,7 +971,7 @@
+         }
+         assert argumentsAcceptable(argtypes, types.memberType(site, m).getParameterTypes(),
+                                    false, false, Warner.noWarnings);
+-        assert null != instantiate(env, site, m, argtypes, typeargtypes, false, false, Warner.noWarnings);
++        assert isPolymorphicSignatureInstance(m);
+         return m;
+     }
+     //where
+@@ -989,6 +988,29 @@
+             return argType;
+         }
+ 
++    /** Recognize if this symbol was marked @PolymorphicSignature in the source. */
++    public boolean isPolymorphicSignatureGeneric(Symbol sym) {
++        return ((sym.flags() & (POLYMORPHIC_SIGNATURE | HYPOTHETICAL)) == POLYMORPHIC_SIGNATURE);
++    }
++    /** Recognize if this symbol was split from a @PolymorphicSignature symbol in the source. */
++    public boolean isPolymorphicSignatureInstance(Symbol sym) {
++        return ((sym.flags() & (POLYMORPHIC_SIGNATURE | HYPOTHETICAL)) == (POLYMORPHIC_SIGNATURE | HYPOTHETICAL));
++    }
++
++    /** Compute a provisional return type for a polymorphic signature call.
++     *  This is just Object.  It might be retroactively changed by Attr.pushTargetType.
++     *  Decode <T> in foo.<T>invoke(bar), for JSR 292 EDR only.
++     */
++    Type initialPolymorphicSignatureResultType(Env<AttrContext> env, List<Type> typeargtypes) {
++        if (!typeargtypes.isEmpty()) {
++            log.warning(env.tree.pos, "type.parameter.on.polymorphic.signature");
++            if (allowTransitionalJSR292) {
++                return typeargtypes.head;
++            }
++        }
++        return syms.objectType;
++    }
++
+     /** Load toplevel or member class with given fully qualified name and
+      *  verify that it is accessible.
+      *  @param env       The current environment.
+@@ -1367,6 +1389,14 @@
+             methodResolutionCache.put(steps.head, sym);
+             steps = steps.tail;
+         }
++        if (allowTransitionalJSR292 &&  // old logic that doesn't use annotations
++            sym.kind >= AMBIGUOUS &&
++            (site == syms.invokeDynamicType ||
++             site == syms.methodHandleType && name == names.invoke)) {
++            // lookup failed; supply an exactly-typed implicit method
++            sym = findPolymorphicSignatureInstance(site, name, null, initialPolymorphicSignatureResultType(env, typeargtypes), argtypes);
++            env.info.varArgs = false;
++        }
+         if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
+             MethodResolutionPhase errPhase =
+                     firstErroneousResolutionPhase();
+@@ -1374,6 +1404,12 @@
+                     pos, site, name, true, argtypes, typeargtypes);
+             env.info.varArgs = errPhase.isVarargsRequired;
+         }
++        if (isPolymorphicSignatureGeneric(sym)) {
++            // Should have expanded this sym already.  Oops.
++            // Somebody is compiling JDK7 source code to a JDK6 target.
++            // Make it a strict warning, since it is unlikely but important.
++            log.strictWarning(pos, "wrong.target.for.polymorphic.signature");
++        }
+         return sym;
+     }
+ 
+diff --git a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
+--- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
++++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
+@@ -652,11 +652,12 @@
+             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++;
++            // Emit the attribute only if the target expects it.
++            if (target.hasMethodHandles()) {
++                int alenIdx = writeAttr(names.PolymorphicSignature);
++                endAttr(alenIdx);
++                acount++;
++            }
+         }
+         return acount;
+     }
+diff --git a/src/share/classes/com/sun/tools/javac/jvm/Target.java b/src/share/classes/com/sun/tools/javac/jvm/Target.java
+--- a/src/share/classes/com/sun/tools/javac/jvm/Target.java
++++ b/src/share/classes/com/sun/tools/javac/jvm/Target.java
+@@ -259,6 +259,14 @@
+         return compareTo(JDK1_7) >= 0;
+     }
+ 
++    /** Does the VM support polymorphic method handle invocation?
++     *  Affects the linkage information output to the classfile.
++     *  An alias for {@code hasInvokedynamic}, since all the JSR 292 features appear together.
++     */
++    public boolean hasMethodHandles() {
++        return hasInvokedynamic();
++    }
++
+     /** Although we may not have support for class literals, should we
+      *  avoid initializing the class that the literal refers to?
+      *  See 4468823
+diff --git a/src/share/classes/com/sun/tools/javac/main/Main.java b/src/share/classes/com/sun/tools/javac/main/Main.java
+--- a/src/share/classes/com/sun/tools/javac/main/Main.java
++++ b/src/share/classes/com/sun/tools/javac/main/Main.java
+@@ -282,6 +282,13 @@
+             }
+         }
+ 
++        // phase this out with JSR 292 PFD
++        if ("no".equals(options.get("allowTransitionalJSR292"))) {
++            options.put("allowTransitionalJSR292", null);
++        } else if (target.hasInvokedynamic() && options.get("allowTransitionalJSR292") == null) {
++            options.put("allowTransitionalJSR292", "allowTransitionalJSR292");
++        }
++
+         // handle this here so it works even if no other options given
+         String showClass = options.get("showClass");
+         if (showClass != null) {
+diff --git a/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/src/share/classes/com/sun/tools/javac/resources/compiler.properties
+--- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties
++++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties
+@@ -124,6 +124,13 @@
+ 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=\
++    MethodHandle invocations require -target 7 runtimes or better
++compiler.warn.wrong.target.for.polymorphic.signature.definition=\
++    MethodHandle API building requires -target 7 runtimes or better; current is -target {0}
++
+ compiler.err.concrete.inheritance.conflict=\
+     methods {0} from {1} and {2} from {3} are inherited with the same signature
+ 
+diff --git a/src/share/classes/com/sun/tools/javac/util/Names.java b/src/share/classes/com/sun/tools/javac/util/Names.java
+--- a/src/share/classes/com/sun/tools/javac/util/Names.java
++++ b/src/share/classes/com/sun/tools/javac/util/Names.java
+@@ -116,6 +116,7 @@
+     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;
+@@ -228,6 +229,7 @@
+         value = fromString("value");
+         getMessage = fromString("getMessage");
+         getClass = fromString("getClass");
++        invoke = fromString("invoke");  //allowTransitionalJSR292 only
+ 
+         TYPE = fromString("TYPE");
+         TYPE_USE = fromString("TYPE_USE");
--- a/meth-edrfix.patch	Thu Aug 12 22:03:52 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,423 +0,0 @@
-Allow new versions of javac to compile old versions of JSR 292 code.
-Allow new versions of the JSR 292 code to omit type parameters from polymorphic signatures.
-Instead, casts will perform the same function, with a clearer meaning and cleaner syntax.
-When the old versions of JSR 292 code have gone away, we will kill the flag 'allowTransitionalJSR292'.
-
-Local definitions:
- "new version of javac" = version which requires @PolymorphicSignature annotations in java.dyn.MethodHandle.
- "old version of JSR 292 code" = version in which java.dyn.MethodHandle lacks @PolymorphicSignature annotations or uses type parameters.
-
-diff --git a/src/share/classes/com/sun/tools/javac/code/Source.java b/src/share/classes/com/sun/tools/javac/code/Source.java
---- a/src/share/classes/com/sun/tools/javac/code/Source.java
-+++ b/src/share/classes/com/sun/tools/javac/code/Source.java
-@@ -171,10 +171,6 @@
-     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 --git a/src/share/classes/com/sun/tools/javac/comp/Attr.java b/src/share/classes/com/sun/tools/javac/comp/Attr.java
---- a/src/share/classes/com/sun/tools/javac/comp/Attr.java
-+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java
-@@ -1121,6 +1121,7 @@
- 
-     public void visitExec(JCExpressionStatement tree) {
-         attribExpr(tree.expr, env);
-+        tree.expr = pushTargetType(syms.voidType, tree.expr);
-         result = null;
-     }
- 
-@@ -1378,23 +1379,22 @@
-                               restype.tsym);
-             }
- 
--            // as a special case, MethodHandle.<T>invoke(abc) and InvokeDynamic.<T>foo(abc)
--            // has type <T>, and T can be a primitive type.
--            if (tree.meth.getTag() == JCTree.SELECT && !typeargtypes.isEmpty()) {
--              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;
--              }
-+            // 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.selected.type.tsym == syms.invokeDynamicType.tsym && rs.recognizeInvokeDynamic) {
-+                    typeargtypesNonRefOK = true;
-+                } else if (mfield.selected.type.tsym == syms.methodHandleType.tsym && rs.recognizeMethodHandles) {
-+                    if (mfield.sym != null && rs.isPolymorphicSignatureInstance(mfield.sym))
-+                        typeargtypesNonRefOK = true;  // invokeExact, invokeGeneric
-+                    else if (methName == names.invoke)
-+                        typeargtypesNonRefOK = true;  // older logic that doesn't use annotations
-+                }
-             }
- 
--            if (!typeargtypesNonRefOK) {
-+            if (!(rs.allowTransitionalJSR292 && typeargtypesNonRefOK)) {
-                 chk.checkRefTypes(tree.typeargs, typeargtypes);
-             }
- 
-@@ -1949,12 +1949,48 @@
-         Type clazztype = attribType(tree.clazz, env);
-         chk.validate(tree.clazz, env);
-         Type exprtype = attribExpr(tree.expr, env, Infer.anyPoly);
-+        tree.expr = pushTargetType(clazztype, tree.expr);
-         Type owntype = chk.checkCastable(tree.expr.pos(), exprtype, clazztype);
-         if (exprtype.constValue() != null)
-             owntype = cfolder.coerce(exprtype, owntype);
-         result = check(tree, capture(owntype), VAL, pkind, pt);
-     }
- 
-+    // A cast or occurrence as an expression statement can affect the linkage of some method calls.
-+    JCExpression pushTargetType(Type targetType, JCExpression expr) {
-+        // JSR 292:  Link some calls according to return type as indicated by a cast.
-+        JCExpression transformedExpr = expr;
-+        JCTypeCast enclosingCast = null;
-+        if (targetType.isPrimitive() && expr.getTag() == JCTree.TYPECAST) {
-+            enclosingCast = (JCTypeCast)expr;
-+            if (types.boxedClass(targetType) == enclosingCast.type.tsym) {
-+                expr = enclosingCast.expr;
-+                // If the expr in turn is a MH.invoke expression,
-+                // we will change (int)(Integer)MH.invoke(...) to (int)MH.invoke(...),
-+                // with a linkage change to return the int directly.
-+            }
-+        }
-+        if (expr.getTag() == JCTree.APPLY) {
-+            JCExpression meth = ((JCMethodInvocation)expr).meth;
-+            if (meth.getTag() == JCTree.SELECT) {
-+                JCFieldAccess methsel = (JCFieldAccess)meth;
-+                if (rs.isPolymorphicSignatureInstance(methsel.sym)) {
-+                    MethodSymbol sym = (MethodSymbol) methsel.sym;
-+                    MethodType oldType = sym.type.asMethodType();
-+                    Symbol newSym = rs.findPolymorphicSignatureInstance(sym.owner.type, sym.name, sym,
-+                                                                        targetType,
-+                                                                        oldType.argtypes);
-+                    if (!rs.isPolymorphicSignatureInstance(newSym))
-+                        throw new AssertionError("can't split poly sym: "+sym);
-+                    methsel.sym = newSym;
-+                    expr.type = targetType;
-+                    transformedExpr = expr;
-+                }
-+            }
-+        }
-+        return transformedExpr;
-+    }
-+
-     public void visitTypeTest(JCInstanceOf tree) {
-         Type exprtype = chk.checkNullOrRefType(
-             tree.expr.pos(), attribExpr(tree.expr, env));
-diff --git a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
---- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
-+++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
-@@ -772,8 +772,14 @@
-             // translates to a classfile attribute.
-             if (!c.type.isErroneous()
-                 && types.isSameType(c.type, syms.polymorphicSignatureType)) {
-+                if (!target.hasMethodHandles()) {
-+                    // Somebody is compiling JDK7 source code to a JDK6 target.
-+                    // Make it a strict warning, since it is unlikely but important.
-+                    log.strictWarning(env.tree.pos(), "wrong.target.for.polymorphic.signature.definition", target.name);
-+                }
-+                // Pull the flag through for better diagnostics, even on a bad target.
-                 s.flags_field |= Flags.POLYMORPHIC_SIGNATURE;
--            }
-+              }
-             if (!annotated.add(a.type.tsym))
-                 log.error(a.pos, "duplicate.annotation");
-         }
-diff --git a/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/src/share/classes/com/sun/tools/javac/comp/Resolve.java
---- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java
-+++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java
-@@ -67,7 +67,9 @@
-     JCDiagnostic.Factory diags;
-     public final boolean boxingEnabled; // = source.allowBoxing();
-     public final boolean varargsEnabled; // = source.allowVarargs();
--    public final boolean allowPolymorphicSignature;
-+    public final boolean recognizeMethodHandles;
-+    public final boolean recognizeInvokeDynamic;
-+    public final boolean allowTransitionalJSR292;
-     private final boolean debugResolve;
- 
-     public static Resolve instance(Context context) {
-@@ -105,7 +107,10 @@
-         varargsEnabled = source.allowVarargs();
-         Options options = Options.instance(context);
-         debugResolve = options.get("debugresolve") != null;
--        allowPolymorphicSignature = source.allowPolymorphicSignature() || options.get("invokedynamic") != null;
-+        allowTransitionalJSR292 = options.get("allowTransitionalJSR292") != null;
-+        Target target = Target.instance(context);
-+        recognizeMethodHandles = allowTransitionalJSR292 || target.hasMethodHandles();
-+        recognizeInvokeDynamic = allowTransitionalJSR292 || target.hasInvokedynamic() && options.get("invokedynamic") != null;
-     }
- 
-     /** error symbols, which are returned when resolution fails
-@@ -301,7 +306,6 @@
-                         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);
- 
-@@ -578,13 +582,15 @@
-         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) {
-+        if (isPolymorphicSignatureGeneric(sym) && recognizeMethodHandles) {
-             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);
-+            Type restype = initialPolymorphicSignatureResultType(env, typeargtypes);
-+            sym = findPolymorphicSignatureInstance(sym.owner.type, sym.name, (MethodSymbol) sym, restype, argtypes);
-+            assert null != instantiate(env, site, sym, argtypes, typeargtypes, false, false, Warner.noWarnings);
-         }
-         try {
-             if (rawInstantiate(env, site, sym, argtypes, typeargtypes,
-@@ -757,12 +763,13 @@
-                       boolean useVarargs,
-                       boolean operator) {
-         Symbol bestSoFar = methodNotFound;
--        if ((site.tsym.flags() & POLYMORPHIC_SIGNATURE) != 0 &&
--            allowPolymorphicSignature &&
-+        if (isPolymorphicSignatureGeneric(site.tsym) && recognizeInvokeDynamic &&
-             site.tag == CLASS &&
-             !(useVarargs | allowBoxing | operator)) {
-             // supply an exactly-typed implicit method in java.dyn.InvokeDynamic
--            bestSoFar = findPolymorphicSignatureInstance(env, site, name, null, argtypes, typeargtypes);
-+            Type restype = initialPolymorphicSignatureResultType(env, typeargtypes);
-+            bestSoFar = findPolymorphicSignatureInstance(site, name, null, restype, argtypes);
-+            assert null != instantiate(env, site, bestSoFar, argtypes, typeargtypes, false, false, Warner.noWarnings);
-         }
-         return findMethod(env,
-                           site,
-@@ -908,43 +915,35 @@
-     /** Find or create an implicit method of exactly the given type (after erasure).
-      *  Searches in a side table, not the main scope of the site.
-      *  This emulates the lookup process required by JSR 292 in JVM.
--     *  @param env       The current environment.
--     *  @param site      The original type from where the selection
--     *                   takes place.
-+     *  @param site      The original type from where the selection takes place.
-      *  @param name      The method's name.
--     *  @param argtypes  The method's value arguments.
--     *  @param typeargtypes The method's type arguments
-+     *  @param spMethod  A template for the implicit method, or null.
-+     *  @param restype   The required return type.
-+     *  @param argtypes  The required argument types.
-      */
--    Symbol findPolymorphicSignatureInstance(Env<AttrContext> env,
--                                            Type site,
-+    Symbol findPolymorphicSignatureInstance(Type site,
-                                             Name name,
-                                             MethodSymbol spMethod,  // sig. poly. method or null if none
--                                            List<Type> argtypes,
--                                            List<Type> typeargtypes) {
--        assert allowPolymorphicSignature;
-+                                            Type restype,
-+                                            List<Type> argtypes) {
-+        assert (recognizeMethodHandles || recognizeInvokeDynamic);
-         //assert site == syms.invokeDynamicType || site == syms.methodHandleType : site;
-         ClassSymbol c = (ClassSymbol) site.tsym;
-         Scope implicit = c.members().next;
-         if (implicit == null) {
-             c.members().next = implicit = new Scope(c);
-         }
--        Type restype;
--        if (typeargtypes.isEmpty()) {
--            restype = syms.objectType;
--        } else {
--            restype = typeargtypes.head;
--            if (!typeargtypes.tail.isEmpty())
--                return methodNotFound;
--        }
-         List<Type> paramtypes = Type.map(argtypes, implicitArgType);
-         long flags;
-         List<Type> exType;
-         if (spMethod != null) {
-+            assert spMethod.owner == site.tsym;
-             exType = spMethod.getThrownTypes();
-             flags = spMethod.flags() & AccessFlags;
-         } else {
-             // make it throw all exceptions
--            //assert(site == syms.invokeDynamicType);
-+            assert recognizeInvokeDynamic;
-+            assert site == syms.invokeDynamicType;
-             exType = List.of(syms.throwableType);
-             flags = PUBLIC | STATIC;
-         }
-@@ -972,7 +971,7 @@
-         }
-         assert argumentsAcceptable(argtypes, types.memberType(site, m).getParameterTypes(),
-                                    false, false, Warner.noWarnings);
--        assert null != instantiate(env, site, m, argtypes, typeargtypes, false, false, Warner.noWarnings);
-+        assert isPolymorphicSignatureInstance(m);
-         return m;
-     }
-     //where
-@@ -989,6 +988,29 @@
-             return argType;
-         }
- 
-+    /** Recognize if this symbol was marked @PolymorphicSignature in the source. */
-+    public boolean isPolymorphicSignatureGeneric(Symbol sym) {
-+        return ((sym.flags() & (POLYMORPHIC_SIGNATURE | HYPOTHETICAL)) == POLYMORPHIC_SIGNATURE);
-+    }
-+    /** Recognize if this symbol was split from a @PolymorphicSignature symbol in the source. */
-+    public boolean isPolymorphicSignatureInstance(Symbol sym) {
-+        return ((sym.flags() & (POLYMORPHIC_SIGNATURE | HYPOTHETICAL)) == (POLYMORPHIC_SIGNATURE | HYPOTHETICAL));
-+    }
-+
-+    /** Compute a provisional return type for a polymorphic signature call.
-+     *  This is just Object.  It might be retroactively changed by Attr.pushTargetType.
-+     *  Decode <T> in foo.<T>invoke(bar), for JSR 292 EDR only.
-+     */
-+    Type initialPolymorphicSignatureResultType(Env<AttrContext> env, List<Type> typeargtypes) {
-+        if (!typeargtypes.isEmpty()) {
-+            log.warning(env.tree.pos, "type.parameter.on.polymorphic.signature");
-+            if (allowTransitionalJSR292) {
-+                return typeargtypes.head;
-+            }
-+        }
-+        return syms.objectType;
-+    }
-+
-     /** Load toplevel or member class with given fully qualified name and
-      *  verify that it is accessible.
-      *  @param env       The current environment.
-@@ -1367,6 +1389,14 @@
-             methodResolutionCache.put(steps.head, sym);
-             steps = steps.tail;
-         }
-+        if (allowTransitionalJSR292 &&  // old logic that doesn't use annotations
-+            sym.kind >= AMBIGUOUS &&
-+            (site == syms.invokeDynamicType ||
-+             site == syms.methodHandleType && name == names.invoke)) {
-+            // lookup failed; supply an exactly-typed implicit method
-+            sym = findPolymorphicSignatureInstance(site, name, null, initialPolymorphicSignatureResultType(env, typeargtypes), argtypes);
-+            env.info.varArgs = false;
-+        }
-         if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
-             MethodResolutionPhase errPhase =
-                     firstErroneousResolutionPhase();
-@@ -1374,6 +1404,12 @@
-                     pos, site, name, true, argtypes, typeargtypes);
-             env.info.varArgs = errPhase.isVarargsRequired;
-         }
-+        if (isPolymorphicSignatureGeneric(sym)) {
-+            // Should have expanded this sym already.  Oops.
-+            // Somebody is compiling JDK7 source code to a JDK6 target.
-+            // Make it a strict warning, since it is unlikely but important.
-+            log.strictWarning(pos, "wrong.target.for.polymorphic.signature");
-+        }
-         return sym;
-     }
- 
-diff --git a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
---- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
-+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
-@@ -652,11 +652,12 @@
-             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++;
-+            // Emit the attribute only if the target expects it.
-+            if (target.hasMethodHandles()) {
-+                int alenIdx = writeAttr(names.PolymorphicSignature);
-+                endAttr(alenIdx);
-+                acount++;
-+            }
-         }
-         return acount;
-     }
-diff --git a/src/share/classes/com/sun/tools/javac/jvm/Target.java b/src/share/classes/com/sun/tools/javac/jvm/Target.java
---- a/src/share/classes/com/sun/tools/javac/jvm/Target.java
-+++ b/src/share/classes/com/sun/tools/javac/jvm/Target.java
-@@ -259,6 +259,14 @@
-         return compareTo(JDK1_7) >= 0;
-     }
- 
-+    /** Does the VM support polymorphic method handle invocation?
-+     *  Affects the linkage information output to the classfile.
-+     *  An alias for {@code hasInvokedynamic}, since all the JSR 292 features appear together.
-+     */
-+    public boolean hasMethodHandles() {
-+        return hasInvokedynamic();
-+    }
-+
-     /** Although we may not have support for class literals, should we
-      *  avoid initializing the class that the literal refers to?
-      *  See 4468823
-diff --git a/src/share/classes/com/sun/tools/javac/main/Main.java b/src/share/classes/com/sun/tools/javac/main/Main.java
---- a/src/share/classes/com/sun/tools/javac/main/Main.java
-+++ b/src/share/classes/com/sun/tools/javac/main/Main.java
-@@ -282,6 +282,13 @@
-             }
-         }
- 
-+        // phase this out with JSR 292 PFD
-+        if ("no".equals(options.get("allowTransitionalJSR292"))) {
-+            options.put("allowTransitionalJSR292", null);
-+        } else if (target.hasInvokedynamic() && options.get("allowTransitionalJSR292") == null) {
-+            options.put("allowTransitionalJSR292", "allowTransitionalJSR292");
-+        }
-+
-         // handle this here so it works even if no other options given
-         String showClass = options.get("showClass");
-         if (showClass != null) {
-diff --git a/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/src/share/classes/com/sun/tools/javac/resources/compiler.properties
---- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties
-+++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties
-@@ -124,6 +124,13 @@
- 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=\
-+    MethodHandle invocations require -target 7 runtimes or better
-+compiler.warn.wrong.target.for.polymorphic.signature.definition=\
-+    MethodHandle API building requires -target 7 runtimes or better; current is -target {0}
-+
- compiler.err.concrete.inheritance.conflict=\
-     methods {0} from {1} and {2} from {3} are inherited with the same signature
- 
-diff --git a/src/share/classes/com/sun/tools/javac/util/Names.java b/src/share/classes/com/sun/tools/javac/util/Names.java
---- a/src/share/classes/com/sun/tools/javac/util/Names.java
-+++ b/src/share/classes/com/sun/tools/javac/util/Names.java
-@@ -116,6 +116,7 @@
-     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;
-@@ -228,6 +229,7 @@
-         value = fromString("value");
-         getMessage = fromString("getMessage");
-         getClass = fromString("getClass");
-+        invoke = fromString("invoke");  //allowTransitionalJSR292 only
- 
-         TYPE = fromString("TYPE");
-         TYPE_USE = fromString("TYPE_USE");
--- a/series	Thu Aug 12 22:03:52 2010 -0700
+++ b/series	Wed Aug 25 22:18:45 2010 -0700
@@ -1,5 +1,4 @@
-# base = aab074677748 in http://hg.openjdk.java.net/bsd-port/bsd-port/langtools [2010-07-10]
-# base = 5e9eabf93833 in http://hg.openjdk.java.net/bsd-port/bsd-port/langtools [2010-08-06]
+# base = d3564f381c7c in http://hg.openjdk.java.net/bsd-port/bsd-port/langtools [2010-08-14]
 
 compile-error-tweak.patch       #+compile-error-tweak
 netbeans-project.patch          #+netbeans-project
@@ -8,12 +7,12 @@
 # pushed to jdk7/hotspot-comp; will be deleted when they get to bsd-port:
 
 # non-pushed files are under review or development, or merely experimental:
-meth.patch                      #-/meth #+5e9eabf93833
-meth-edrfix.patch               #-/meth #+5e9eabf93833
-indy-bsm-6964498.patch          #-/meth #+5e9eabf93833
-meth-ldc-6939203.patch          #-/meth #+5e9eabf93833 #-/experimental #-testable
-meth-ver-6949040.patch          #-/meth #+5e9eabf93833 #-testable
-meth-anno.patch                 #-/meth #+5e9eabf93833 #-/experimental #-testable
+meth.patch                      #-/meth #+d3564f381c7c
+meth-edrfix-6979327.patch       #-/meth #+d3564f381c7c
+indy-bsm-6964498.patch          #-/meth #+d3564f381c7c
+meth-ldc-6939203.patch          #-/meth #+d3564f381c7c #-/experimental #-testable
+meth-ver-6949040.patch          #-/meth #+d3564f381c7c #-testable
+meth-anno.patch                 #-/meth #+d3564f381c7c #-/experimental #-testable
 
 # Keep these separate, for debugging and review:
 dyncast.patch   #+dyncast       #-/dyncast