changeset 748:cd26d488d641

Fixed issue with defender method and separate compilation. Default method symbol was not restored by ClassReader.
author mcimadamore
date Fri, 29 Oct 2010 18:11:50 +0100
parents fa6868eac2c4
children b3cc870e2c67
files src/share/classes/com/sun/tools/javac/jvm/ClassReader.java src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java test/tools/javac/defender/Pos09.java test/tools/javac/defender/pkg1/A.java
diffstat 4 files changed, 108 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Fri Oct 29 13:38:49 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Fri Oct 29 18:11:50 2010 +0100
@@ -102,6 +102,10 @@
      */
     boolean allowAnnotations;
 
+    /** Switch: allow defender methods
+     */
+    boolean allowDefenderMethods;
+
     /** Switch: preserve parameter names from the variable table.
      */
     public boolean saveParameterNames;
@@ -267,6 +271,7 @@
         allowGenerics    = source.allowGenerics();
         allowVarargs     = source.allowVarargs();
         allowAnnotations = source.allowAnnotations();
+        allowDefenderMethods = source.allowDefenderMethods();
         saveParameterNames = options.isSet("save-parameter-names");
         cacheCompletionFailure = options.isUnset("dev");
         preferSource = "source".equals(options.get("-Xprefer"));
@@ -1143,6 +1148,18 @@
                     attachTypeAnnotations(sym);
                 }
             },
+            new AttributeReader(names.Defender, V51, MEMBER_ATTRIBUTE) {
+                @Override
+                boolean accepts(AttributeKind kind) {
+                    return super.accepts(kind) && allowDefenderMethods;
+                }
+
+                void read(Symbol sym, int attrLen) {
+                    int newbp = bp + attrLen;
+                    ((MethodSymbol)sym).getDefaultImpl(); //forces attribute to be read
+                    bp = newbp;
+                }
+            },
 
 
             // The following attributes for a Code attribute are not currently handled
@@ -1163,8 +1180,6 @@
             printCCF("ccf.unrecognized.attribute", attrName);
     }
 
-
-
     void readEnclosingMethodAttr(Symbol sym) {
         // sym is a nested class with an "Enclosing Method" attribute
         // remove sym from it's current owners scope and place it in
@@ -1902,7 +1917,22 @@
                                       type.getThrownTypes(),
                                       syms.methodClass);
         }
-        MethodSymbol m = new MethodSymbol(flags, name, type, currentOwner);
+        MethodSymbol m = (flags & DEFENDER) == 0 ?
+            new MethodSymbol(flags, name, type, currentOwner) :
+            new MethodSymbol(flags, name, type, currentOwner) {
+                @Override
+                public Symbol getDefaultImpl() {
+                    if (defaultImpl != null) return defaultImpl;
+                    ClassSymbol self = (ClassSymbol)owner;
+                    ClassSymbol c = readClassSymbol(nextChar());
+                    NameAndType nt = (NameAndType)readPool(nextChar());
+                    c.complete();
+                    MethodSymbol m = findMethod(nt, c.members_field, self.flags());
+                    if (nt != null && m == null)
+                        throw badClassFile("bad.enclosing.method", self);
+                    return defaultImpl = m;
+            }
+        };
         if (saveParameterNames)
             initParameterNames(m);
         Symbol prevOwner = currentOwner;
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Fri Oct 29 13:38:49 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Fri Oct 29 18:11:50 2010 +0100
@@ -645,9 +645,9 @@
             return 0;
 
         int alenIdx = writeAttr(names.Defender);
-        ClassSymbol enclClass = m.enclClass();
-        databuf.appendChar(pool.put(enclClass));
-        databuf.appendChar(pool.put(nameType(m.getDefaultImpl())));
+        Symbol defaultImpl = m.getDefaultImpl();
+        databuf.appendChar(pool.put(defaultImpl.owner));
+        databuf.appendChar(pool.put(nameType(defaultImpl)));
         endAttr(alenIdx);
         return 1;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/defender/Pos09.java	Fri Oct 29 18:11:50 2010 +0100
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary check that Defender bytecode attribute is used to restore default method as expected
+ * @author  Maurizio Cimadamore
+ * @compile pkg1/A.java
+ * @compile Pos09.java
+ */
+
+import pkg1.A;
+
+class Pos09 {
+    interface B {
+        extension void m() default A.m;
+    }
+
+    interface C extends A.I, B { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/defender/pkg1/A.java	Fri Oct 29 18:11:50 2010 +0100
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+package pkg1;
+
+public class A {
+    public interface I {
+        extension void m() default A.m;
+    }
+
+    public static void m(Object o) {}
+}