mcimadamore@1393: /* mcimadamore@1393: * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. mcimadamore@1393: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. mcimadamore@1393: * mcimadamore@1393: * This code is free software; you can redistribute it and/or modify it mcimadamore@1393: * under the terms of the GNU General Public License version 2 only, as mcimadamore@1393: * published by the Free Software Foundation. mcimadamore@1393: * mcimadamore@1393: * This code is distributed in the hope that it will be useful, but WITHOUT mcimadamore@1393: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or mcimadamore@1393: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License mcimadamore@1393: * version 2 for more details (a copy is included in the LICENSE file that mcimadamore@1393: * accompanied this code). mcimadamore@1393: * mcimadamore@1393: * You should have received a copy of the GNU General Public License version mcimadamore@1393: * 2 along with this work; if not, write to the Free Software Foundation, mcimadamore@1393: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. mcimadamore@1393: * mcimadamore@1393: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA mcimadamore@1393: * or visit www.oracle.com if you need additional information or have any mcimadamore@1393: * questions. mcimadamore@1393: */ mcimadamore@1393: mcimadamore@1393: /* mcimadamore@1393: * @test mcimadamore@1393: * @summary check that code attributed for default methods is correctly generated mcimadamore@1393: */ mcimadamore@1393: mcimadamore@1393: import com.sun.tools.classfile.AccessFlags; mcimadamore@1393: import com.sun.tools.classfile.Attribute; mcimadamore@1393: import com.sun.tools.classfile.ClassFile; mcimadamore@1393: import com.sun.tools.classfile.ConstantPool.*; mcimadamore@1393: import com.sun.tools.classfile.Code_attribute; mcimadamore@1393: import com.sun.tools.classfile.Instruction; mcimadamore@1393: import com.sun.tools.classfile.Method; mcimadamore@1393: mcimadamore@1393: import com.sun.tools.classfile.Opcode; mcimadamore@1393: import java.io.*; mcimadamore@1393: mcimadamore@1393: public class TestDefaultBody { mcimadamore@1393: mcimadamore@1393: interface TestInterface { mcimadamore@1393: int no_default(int i); mcimadamore@1393: default int yes_default(int i) { return impl(this, i); } mcimadamore@1393: } mcimadamore@1393: mcimadamore@1393: static int impl(TestInterface ti, int i) { return 0; } mcimadamore@1393: mcimadamore@1393: static final String TARGET_CLASS_NAME = "TestDefaultBody"; mcimadamore@1393: static final String TARGET_NAME = "impl"; mcimadamore@1393: static final String TARGET_TYPE = "(LTestDefaultBody$TestInterface;I)I"; mcimadamore@1393: static final String SUBTEST_NAME = TestInterface.class.getName() + ".class"; mcimadamore@1393: static final String TEST_METHOD_NAME = "yes_default"; mcimadamore@1393: mcimadamore@1393: public static void main(String... args) throws Exception { mcimadamore@1393: new TestDefaultBody().run(); mcimadamore@1393: } mcimadamore@1393: mcimadamore@1393: public void run() throws Exception { mcimadamore@1393: String workDir = System.getProperty("test.classes"); mcimadamore@1393: File compiledTest = new File(workDir, SUBTEST_NAME); mcimadamore@1393: verifyDefaultBody(compiledTest); mcimadamore@1393: } mcimadamore@1393: mcimadamore@1393: void verifyDefaultBody(File f) { mcimadamore@1393: System.err.println("verify: " + f); mcimadamore@1393: try { mcimadamore@1393: ClassFile cf = ClassFile.read(f); mcimadamore@1393: Method testMethod = null; mcimadamore@1393: Code_attribute codeAttr = null; mcimadamore@1393: for (Method m : cf.methods) { mcimadamore@1393: codeAttr = (Code_attribute)m.attributes.get(Attribute.Code); mcimadamore@1393: String mname = m.getName(cf.constant_pool); mcimadamore@1393: if (mname.equals(TEST_METHOD_NAME)) { mcimadamore@1393: testMethod = m; mcimadamore@1393: break; mcimadamore@1393: } else { mcimadamore@1393: codeAttr = null; mcimadamore@1393: } mcimadamore@1393: } mcimadamore@1393: if (testMethod == null) { mcimadamore@1393: throw new Error("Test method not found"); mcimadamore@1393: } mcimadamore@1393: if (testMethod.access_flags.is(AccessFlags.ACC_ABSTRACT)) { mcimadamore@1393: throw new Error("Test method is abstract"); mcimadamore@1393: } mcimadamore@1393: if (codeAttr == null) { mcimadamore@1393: throw new Error("Code attribute in test method not found"); mcimadamore@1393: } mcimadamore@1393: mcimadamore@1393: boolean found = false; mcimadamore@1393: for (Instruction instr : codeAttr.getInstructions()) { mcimadamore@1393: if (instr.getOpcode() == Opcode.INVOKESTATIC) { mcimadamore@1393: found = true; mcimadamore@1393: int pc_index = instr.getShort(1); mcimadamore@1393: CONSTANT_Methodref_info mref = (CONSTANT_Methodref_info)cf.constant_pool.get(pc_index); mcimadamore@1393: String className = mref.getClassName(); mcimadamore@1393: String targetName = mref.getNameAndTypeInfo().getName(); mcimadamore@1393: String targetType = mref.getNameAndTypeInfo().getType(); mcimadamore@1393: mcimadamore@1393: if (!className.equals(TARGET_CLASS_NAME)) { mcimadamore@1393: throw new Error("unexpected class in default method body " + className); mcimadamore@1393: } mcimadamore@1393: if (!targetName.equals(TARGET_NAME)) { mcimadamore@1393: throw new Error("unexpected method name in default method body " + targetName); mcimadamore@1393: } mcimadamore@1393: if (!targetType.equals(TARGET_TYPE)) { mcimadamore@1393: throw new Error("unexpected method type in default method body " + targetType); mcimadamore@1393: } mcimadamore@1393: break; mcimadamore@1393: } mcimadamore@1393: } mcimadamore@1393: mcimadamore@1393: if (!found) { mcimadamore@1393: throw new Error("no invokestatic found in default method body"); mcimadamore@1393: } mcimadamore@1393: } catch (Exception e) { mcimadamore@1393: e.printStackTrace(); mcimadamore@1393: throw new Error("error reading " + f +": " + e); mcimadamore@1393: } mcimadamore@1393: } mcimadamore@1393: }