hotspot/test/compiler/jsr292/methodHandleExceptions/TestAMEnotNPE.java
changeset 20298 861da81238ee
child 21770 e8932d2fda2c
equal deleted inserted replaced
20297:74ad297e3844 20298:861da81238ee
       
     1 /*
       
     2  * Copyright (c) 2013, 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 import java.lang.reflect.InvocationTargetException;
       
    26 import jdk.internal.org.objectweb.asm.ClassWriter;
       
    27 import jdk.internal.org.objectweb.asm.Handle;
       
    28 import jdk.internal.org.objectweb.asm.MethodVisitor;
       
    29 import jdk.internal.org.objectweb.asm.Opcodes;
       
    30 
       
    31 /**
       
    32  * @test
       
    33  * @bug 8025260
       
    34  * @summary Ensure that AbstractMethodError is thrown, not NullPointerException, through MethodHandles::jump_from_method_handle code path
       
    35  *
       
    36  * @compile -XDignore.symbol.file ByteClassLoader.java I.java C.java TestAMEnotNPE.java
       
    37  * @run main/othervm TestAMEnotNPE
       
    38  */
       
    39 
       
    40 public class TestAMEnotNPE implements Opcodes {
       
    41 
       
    42     /**
       
    43      * The bytes for D, a NOT abstract class extending abstract class C
       
    44      * without supplying an implementation for abstract method m.
       
    45      * There is a default method in the interface I, but it should lose to
       
    46      * the abstract class.
       
    47 
       
    48      class D extends C {
       
    49         D() { super(); }
       
    50         // does not define m
       
    51      }
       
    52 
       
    53      * @return
       
    54      * @throws Exception
       
    55      */
       
    56     public static byte[] bytesForD() throws Exception {
       
    57 
       
    58         ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);
       
    59         MethodVisitor mv;
       
    60 
       
    61         cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, "D", null, "C", null);
       
    62 
       
    63         {
       
    64             mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
       
    65             mv.visitCode();
       
    66             mv.visitVarInsn(ALOAD, 0);
       
    67             mv.visitMethodInsn(INVOKESPECIAL, "C", "<init>", "()V");
       
    68             mv.visitInsn(RETURN);
       
    69             mv.visitMaxs(0, 0);
       
    70             mv.visitEnd();
       
    71         }
       
    72         cw.visitEnd();
       
    73 
       
    74         return cw.toByteArray();
       
    75     }
       
    76 
       
    77 
       
    78     /**
       
    79      * The bytecodes for an invokeExact of a particular methodHandle, I.m, invoked on a D
       
    80 
       
    81         class T {
       
    82            T() { super(); } // boring constructor
       
    83            int test() {
       
    84               MethodHandle mh = `I.m():int`;
       
    85               D d = new D();
       
    86               return mh.invokeExact(d); // Should explode here, AbstractMethodError
       
    87            }
       
    88         }
       
    89 
       
    90      * @return
       
    91      * @throws Exception
       
    92      */
       
    93     public static byte[] bytesForT() throws Exception {
       
    94 
       
    95         ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);
       
    96         MethodVisitor mv;
       
    97 
       
    98         cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, "T", null, "java/lang/Object", null);
       
    99         {
       
   100             mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
       
   101             mv.visitCode();
       
   102             mv.visitVarInsn(ALOAD, 0);
       
   103             mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
       
   104             mv.visitInsn(RETURN);
       
   105             mv.visitMaxs(0,0);
       
   106             mv.visitEnd();
       
   107         }
       
   108         {
       
   109             mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "test", "()I", null, null);
       
   110             mv.visitCode();
       
   111             mv.visitLdcInsn(new Handle(Opcodes.H_INVOKEINTERFACE, "I", "m", "()I"));
       
   112             mv.visitTypeInsn(NEW, "D");
       
   113             mv.visitInsn(DUP);
       
   114             mv.visitMethodInsn(INVOKESPECIAL, "D", "<init>", "()V");
       
   115             mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", "invokeExact", "(LI;)I");
       
   116             mv.visitInsn(IRETURN);
       
   117             mv.visitMaxs(0,0);
       
   118             mv.visitEnd();
       
   119         }
       
   120         cw.visitEnd();
       
   121         return cw.toByteArray();
       
   122     }
       
   123 
       
   124     public static void main(String args[] ) throws Throwable {
       
   125         ByteClassLoader bcl = new ByteClassLoader();
       
   126         Class<?> d = bcl.loadBytes("D", bytesForD());
       
   127         Class<?> t = bcl.loadBytes("T", bytesForT());
       
   128         try {
       
   129           Object result = t.getMethod("test").invoke(null);
       
   130           System.out.println("Expected AbstractMethodError wrapped in InvocationTargetException, saw no exception");
       
   131           throw new Error("Missing expected exception");
       
   132         } catch (InvocationTargetException e) {
       
   133             Throwable th = e.getCause();
       
   134             if (th instanceof AbstractMethodError) {
       
   135                 th.printStackTrace(System.out);
       
   136                 System.out.println("PASS, saw expected exception (AbstractMethodError, wrapped in InvocationTargetException).");
       
   137             } else {
       
   138                 System.out.println("Expected AbstractMethodError wrapped in InvocationTargetException, saw " + th);
       
   139                 throw th;
       
   140             }
       
   141         }
       
   142     }
       
   143 }