changeset 856:a953c0c02c7c

Regression: compiler does not generate bytecode attribute for defender methods. *) Added regression test that checks existence/well-formedness of the defender method attribute. *) Better javap output for defender method attributes: public abstract int add(int); flags: ACC_PUBLIC, ACC_ABSTRACT, 0x200 Defender: #6.#7 // TraitImpl.add Instead of the old output: public abstract int add(int); flags: ACC_PUBLIC, ACC_ABSTRACT, 0x200 Defender: length = 0x4 00 06 00 07
author mcimadamore
date Tue, 18 Jan 2011 12:22:52 +0000
parents 9a616df38d88
children 84a6bb3ef295
files src/share/classes/com/sun/tools/classfile/Attribute.java src/share/classes/com/sun/tools/classfile/Defender_attribute.java src/share/classes/com/sun/tools/javac/jvm/Target.java src/share/classes/com/sun/tools/javap/AttributeWriter.java test/tools/javac/defender/TestDefenderAttribute.java
diffstat 5 files changed, 113 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/classfile/Attribute.java	Mon Jan 17 14:34:40 2011 +0000
+++ b/src/share/classes/com/sun/tools/classfile/Attribute.java	Tue Jan 18 12:22:52 2011 +0000
@@ -43,7 +43,7 @@
     public static final String Code                     = "Code";
     public static final String ConstantValue            = "ConstantValue";
     public static final String CompilationID            = "CompilationID";
-    public static final String Defender               = "Defender";
+    public static final String Defender                 = "Defender";
     public static final String Deprecated               = "Deprecated";
     public static final String EnclosingMethod          = "EnclosingMethod";
     public static final String Exceptions               = "Exceptions";
@@ -123,6 +123,7 @@
                 standardAttributes.put(RuntimeInvisibleTypeAnnotations, RuntimeInvisibleTypeAnnotations_attribute.class);
                 standardAttributes.put(Signature,     Signature_attribute.class);
                 standardAttributes.put(SourceID, SourceID_attribute.class);
+                standardAttributes.put(Defender, Defender_attribute.class);
             }
 
             standardAttributes.put(SourceDebugExtension, SourceDebugExtension_attribute.class);
--- a/src/share/classes/com/sun/tools/classfile/Defender_attribute.java	Mon Jan 17 14:34:40 2011 +0000
+++ b/src/share/classes/com/sun/tools/classfile/Defender_attribute.java	Tue Jan 18 12:22:52 2011 +0000
@@ -67,6 +67,12 @@
         return constant_pool.getNameAndTypeInfo(method_index).getName();
     }
 
+    public String getMethodType(ConstantPool constant_pool) throws ConstantPoolException {
+        if (method_index == 0)
+            return "";
+        return constant_pool.getNameAndTypeInfo(method_index).getType();
+    }
+
     public final int class_index;
     public final int method_index;
 }
--- a/src/share/classes/com/sun/tools/javac/jvm/Target.java	Mon Jan 17 14:34:40 2011 +0000
+++ b/src/share/classes/com/sun/tools/javac/jvm/Target.java	Tue Jan 18 12:22:52 2011 +0000
@@ -102,6 +102,7 @@
         tab.put("5", JDK1_5);
         tab.put("6", JDK1_6);
         tab.put("7", JDK1_7);
+        tab.put("8", JDK1_8);
     }
 
     public final String name;
@@ -113,7 +114,7 @@
         this.minorVersion = minorVersion;
     }
 
-    public static final Target DEFAULT = JDK1_7;
+    public static final Target DEFAULT = JDK1_8;
 
     public static Target lookup(String name) {
         return tab.get(name);
--- a/src/share/classes/com/sun/tools/javap/AttributeWriter.java	Mon Jan 17 14:34:40 2011 +0000
+++ b/src/share/classes/com/sun/tools/javap/AttributeWriter.java	Tue Jan 18 12:22:52 2011 +0000
@@ -213,7 +213,7 @@
     }
     
     public Void visitDefender(Defender_attribute attr, Void ignore) {
-        print("Defender: #" + attr.method_index);
+        print("Defender: #" + attr.class_index + ".#" + attr.method_index);
         tab();
         print("// " + getJavaClassName(attr));
         if (attr.method_index != 0)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/defender/TestDefenderAttribute.java	Tue Jan 18 12:22:52 2011 +0000
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2011, 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 attribute is correctly generated
+ * @run main TestDefenderAttribute
+ */
+
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPool.*;
+import com.sun.tools.classfile.Defender_attribute;
+import com.sun.tools.classfile.Method;
+
+import java.io.*;
+
+public class TestDefenderAttribute {
+
+    interface TestInterface {
+        int no_defender(int i);
+        int defender(int i) default impl;
+    }
+
+    static int impl(TestInterface ti, int i) { return 0; }
+
+    static final String TARGET_CLASS_NAME = "TestDefenderAttribute";
+    static final String TARGET_NAME = "impl";
+    static final String TARGET_TYPE = "(LTestDefenderAttribute$TestInterface;I)I";
+    static final String SUBTEST_NAME = TestInterface.class.getName() + ".class";
+    static final String TEST_METHOD_NAME = "defender";
+
+    public static void main(String... args) throws Exception {
+        new TestDefenderAttribute().run();
+    }
+
+    public void run() throws Exception {
+        String workDir = System.getProperty("test.classes");
+        File compiledTest = new File(workDir, SUBTEST_NAME);
+        verifyDefenderAttribute(compiledTest);
+    }
+
+    void verifyDefenderAttribute(File f) {
+        System.err.println("verify: " + f);
+        try {
+            ClassFile cf = ClassFile.read(f);
+            Method testMethod = null;
+            Defender_attribute defenderAttr = null;
+            for (Method m : cf.methods) {
+                defenderAttr = (Defender_attribute)m.attributes.get(Attribute.Defender);
+                String mname = m.getName(cf.constant_pool);
+                if (defenderAttr != null) {
+                    if (!mname.equals(TEST_METHOD_NAME)) {
+                        throw new Error("unexpected Defender attribute on method " + m);
+                    } else {
+                        testMethod = m;
+                        break;
+                    }
+                }
+            }
+            if (testMethod == null) {
+                throw new Error("Test method not found");
+            }
+            String className = defenderAttr.getClassName(cf.constant_pool);
+            String targetName = defenderAttr.getMethodName(cf.constant_pool);
+            String targetType = defenderAttr.getMethodType(cf.constant_pool);
+
+            if (!className.equals(TARGET_CLASS_NAME)) {
+                throw new Error("unexpected class in defender method attribute " + className);
+            }
+            if (!targetName.equals(TARGET_NAME)) {
+                throw new Error("unexpected method name in defender method attribute " + targetName);
+            }
+            if (!targetType.equals(TARGET_TYPE)) {
+                throw new Error("unexpected method type in defender method attribute " + targetType);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new Error("error reading " + f +": " + e);
+        }
+    }
+}