1 /* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 /* 26 * @test 27 * @bug 8087342 28 * @summary Test linkresolver search static, instance and overpass duplicates 29 * @modules java.base/jdk.internal.org.objectweb.asm 30 * @run main/othervm -Xverify:none TestStaticandInstance 31 */ 32 33 34 import java.util.*; 35 import jdk.internal.org.objectweb.asm.*; 36 import static jdk.internal.org.objectweb.asm.Opcodes.*; 37 38 public class TestStaticandInstance { 39 static final String stringC = "C"; 40 static final String stringD = "D"; 41 static final String stringI = "I"; 42 43 public static void main(String args[]) throws Throwable { 44 ClassLoader cl = new ClassLoader() { 45 public Class<?> loadClass(String name) throws ClassNotFoundException { 46 Class retClass; 47 if ((retClass = findLoadedClass(name)) != null) { 48 return retClass; 49 } 50 if (stringC.equals(name)) { 51 byte[] classFile=dumpC(); 52 return defineClass(stringC, classFile, 0, classFile.length); 53 } 54 if (stringD.equals(name)) { 55 byte[] classFile=dumpD(); 56 return defineClass(stringD, classFile, 0, classFile.length); 57 } 58 if (stringI.equals(name)) { 59 byte[] classFile=dumpI(); 60 return defineClass(stringI, classFile, 0, classFile.length); 61 } 62 return super.loadClass(name); 63 } 64 }; 65 66 Class classC = cl.loadClass(stringC); 67 Class classI = cl.loadClass(stringI); 68 69 try { 70 int staticret = (Integer)cl.loadClass(stringD).getDeclaredMethod("CallStatic").invoke(null); 71 if (staticret != 1) { 72 throw new RuntimeException("invokestatic failed to call correct method"); 73 } 74 System.out.println("staticret: " + staticret); // should be 1 75 76 int invokeinterfaceret = (Integer)cl.loadClass(stringD).getDeclaredMethod("CallInterface").invoke(null); 77 if (invokeinterfaceret != 0) { 78 throw new RuntimeException(String.format("Expected java.lang.AbstractMethodError, got %d", invokeinterfaceret)); 79 } 80 System.out.println("invokeinterfaceret: AbstractMethodError"); 81 82 int invokevirtualret = (Integer)cl.loadClass(stringD).getDeclaredMethod("CallVirtual").invoke(null); 83 if (invokevirtualret != 0) { 84 throw new RuntimeException(String.format("Expected java.lang.IncompatibleClassChangeError, got %d", invokevirtualret)); 85 } 86 System.out.println("invokevirtualret: IncompatibleClassChangeError"); 87 } catch (java.lang.Throwable e) { 88 throw new RuntimeException("Unexpected exception: " + e.getMessage()); 89 } 90 } 91 92 /* 93 interface I { 94 public int m(); // abstract 95 default int q() { return 3; } // trigger defmeth processing: C gets AME overpass 96 } 97 98 // C gets static, private and AME overpass m()I with -Xverify:none 99 class C implements I { 100 static int m() { return 1;} // javac with "n()" and patch to "m()" 101 private int m() { return 2;} // javac with public and patch to private 102 } 103 104 public class D { 105 public static int CallStatic() { 106 int staticret = C.m(); // javac with "C.n" and patch to "C.m" 107 return staticret; 108 } 109 public static int CallInterface() throws AbstractMethodError{ 110 try { 111 I myI = new C(); 112 return myI.m(); 113 } catch (java.lang.AbstractMethodError e) { 114 return 0; // for success 115 } 116 } 117 public static int CallVirtual() { 118 try { 119 C myC = new C(); 120 return myC.m(); 121 } catch (java.lang.IncompatibleClassChangeError e) { 122 return 0; // for success 123 } 124 } 125 } 126 */ 127 128 public static byte[] dumpC() { 129 130 ClassWriter cw = new ClassWriter(0); 131 FieldVisitor fv; 132 MethodVisitor mv; 133 AnnotationVisitor av0; 134 135 cw.visit(52, ACC_SUPER, "C", null, "java/lang/Object", new String[] { "I" }); 136 137 { 138 mv = cw.visitMethod(0, "<init>", "()V", null, null); 139 mv.visitCode(); 140 mv.visitVarInsn(ALOAD, 0); 141 mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); 142 mv.visitInsn(RETURN); 143 mv.visitMaxs(1, 1); 144 mv.visitEnd(); 145 } 146 { 147 mv = cw.visitMethod(ACC_STATIC, "m", "()I", null, null); 148 mv.visitCode(); 149 mv.visitInsn(ICONST_1); 150 mv.visitInsn(IRETURN); 151 mv.visitMaxs(1, 0); 152 mv.visitEnd(); 153 } 154 { 155 mv = cw.visitMethod(ACC_PRIVATE, "m", "()I", null, null); 156 mv.visitCode(); 157 mv.visitInsn(ICONST_2); 158 mv.visitInsn(IRETURN); 159 mv.visitMaxs(1, 1); 160 mv.visitEnd(); 161 } 162 cw.visitEnd(); 163 164 return cw.toByteArray(); 165 } 166 167 public static byte[] dumpD () { 168 169 ClassWriter cw = new ClassWriter(0); 170 FieldVisitor fv; 171 MethodVisitor mv; 172 AnnotationVisitor av0; 173 174 cw.visit(52, ACC_PUBLIC + ACC_SUPER, "D", null, "java/lang/Object", null); 175 176 { 177 mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); 178 mv.visitCode(); 179 mv.visitVarInsn(ALOAD, 0); 180 mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); 181 mv.visitInsn(RETURN); 182 mv.visitMaxs(1, 1); 183 mv.visitEnd(); 184 } 185 { 186 mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "CallStatic", "()I", null, null); 187 mv.visitCode(); 188 mv.visitMethodInsn(INVOKESTATIC, "C", "m", "()I", false); 189 mv.visitVarInsn(ISTORE, 0); 190 mv.visitVarInsn(ILOAD, 0); 191 mv.visitInsn(IRETURN); 192 mv.visitMaxs(1, 1); 193 mv.visitEnd(); 194 } 195 { 196 mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "CallInterface", "()I", null, new String[] { "java/lang/AbstractMethodError" }); 197 mv.visitCode(); 198 Label l0 = new Label(); 199 Label l1 = new Label(); 200 Label l2 = new Label(); 201 mv.visitTryCatchBlock(l0, l1, l2, "java/lang/AbstractMethodError"); 202 mv.visitLabel(l0); 203 mv.visitTypeInsn(NEW, "C"); 204 mv.visitInsn(DUP); 205 mv.visitMethodInsn(INVOKESPECIAL, "C", "<init>", "()V", false); 206 mv.visitVarInsn(ASTORE, 0); 207 mv.visitVarInsn(ALOAD, 0); 208 mv.visitMethodInsn(INVOKEINTERFACE, "I", "m", "()I", true); 209 mv.visitLabel(l1); 210 mv.visitInsn(IRETURN); 211 mv.visitLabel(l2); 212 mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/AbstractMethodError"}); 213 mv.visitVarInsn(ASTORE, 0); 214 mv.visitInsn(ICONST_0); 215 mv.visitInsn(IRETURN); 216 mv.visitMaxs(2, 1); 217 mv.visitEnd(); 218 } 219 { 220 mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "CallVirtual", "()I", null, null); 221 mv.visitCode(); 222 Label l0 = new Label(); 223 Label l1 = new Label(); 224 Label l2 = new Label(); 225 mv.visitTryCatchBlock(l0, l1, l2, "java/lang/IncompatibleClassChangeError"); 226 mv.visitLabel(l0); 227 mv.visitTypeInsn(NEW, "C"); 228 mv.visitInsn(DUP); 229 mv.visitMethodInsn(INVOKESPECIAL, "C", "<init>", "()V", false); 230 mv.visitVarInsn(ASTORE, 0); 231 mv.visitVarInsn(ALOAD, 0); 232 mv.visitMethodInsn(INVOKEVIRTUAL, "C", "m", "()I", false); 233 mv.visitLabel(l1); 234 mv.visitInsn(IRETURN); 235 mv.visitLabel(l2); 236 mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/IncompatibleClassChangeError"}); 237 mv.visitVarInsn(ASTORE, 0); 238 mv.visitInsn(ICONST_0); 239 mv.visitInsn(IRETURN); 240 mv.visitMaxs(2, 1); 241 mv.visitEnd(); 242 } 243 cw.visitEnd(); 244 245 return cw.toByteArray(); 246 } 247 248 public static byte[] dumpI() { 249 250 ClassWriter cw = new ClassWriter(0); 251 FieldVisitor fv; 252 MethodVisitor mv; 253 AnnotationVisitor av0; 254 255 cw.visit(52, ACC_ABSTRACT + ACC_INTERFACE, "I", null, "java/lang/Object", null); 256 257 { 258 mv = cw.visitMethod(ACC_PUBLIC + ACC_ABSTRACT, "m", "()I", null, null); 259 mv.visitEnd(); 260 } 261 { 262 mv = cw.visitMethod(ACC_PUBLIC, "q", "()I", null, null); 263 mv.visitCode(); 264 mv.visitInsn(ICONST_3); 265 mv.visitInsn(IRETURN); 266 mv.visitMaxs(1, 1); 267 mv.visitEnd(); 268 } 269 cw.visitEnd(); 270 271 return cw.toByteArray(); 272 } 273 }