/*
 * Copyright (c) 2013, 2015, 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
 * @bug 8025260 8016839
 * @summary Ensure that AbstractMethodError and IllegalAccessError are thrown appropriately, not NullPointerException
 * @modules java.base/jdk.internal.org.objectweb.asm
 * @library / .
 *
 * @build p.*
 * @run main/othervm compiler.jsr292.methodHandleExceptions.TestAMEnotNPE
 * @run main/othervm -Xint compiler.jsr292.methodHandleExceptions.TestAMEnotNPE
 * @run main/othervm -Xcomp compiler.jsr292.methodHandleExceptions.TestAMEnotNPE
 */

package compiler.jsr292.methodHandleExceptions;

import p.Dok;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.Handle;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PRIVATE;
import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC;
import static jdk.internal.org.objectweb.asm.Opcodes.ACC_STATIC;
import static jdk.internal.org.objectweb.asm.Opcodes.ACC_SUPER;
import static jdk.internal.org.objectweb.asm.Opcodes.ALOAD;
import static jdk.internal.org.objectweb.asm.Opcodes.ILOAD;
import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESPECIAL;
import static jdk.internal.org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
import static jdk.internal.org.objectweb.asm.Opcodes.IRETURN;
import static jdk.internal.org.objectweb.asm.Opcodes.LLOAD;
import static jdk.internal.org.objectweb.asm.Opcodes.RETURN;
import static jdk.internal.org.objectweb.asm.Opcodes.V1_8;

public class TestAMEnotNPE {

    static boolean writeJarFiles = false;
    static boolean readJarFiles = false;

    /**
     * Optional command line parameter (any case-insensitive prefix of)
     * "writejarfiles" or "readjarfiles".
     *
     * "Writejarfiles" creates a jar file for each different set of tested classes.
     * "Readjarfiles" causes the classloader to use the copies of the classes
     * found in the corresponding jar files.
     *
     * Jarfilenames look something like pD_ext_pF (p.D extends p.F)
     * and qD_m_pp_imp_pI (q.D with package-private m implements p.I)
     *
     */
    public static void main(String args[]) throws Throwable {
        ArrayList<Throwable> lt = new ArrayList<Throwable>();

        if (args.length > 0) {
            String a0 = args[0].toLowerCase();
            if (a0.length() > 0) {
                writeJarFiles = ("writejarfiles").startsWith(a0);
                readJarFiles = ("readjarfiles").startsWith(a0);
            }
            if (!(writeJarFiles || readJarFiles)) {
                throw new Error("Command line parameter (if any) should be prefix of writeJarFiles or readJarFiles");
            }
        }

        try {
            System.out.println("TRYING p.D.m PRIVATE interface-invoked as p.I.m, p.D extends p.F, p.F.m FINAL");
            tryAndCheckThrown(lt, bytesForDprivateSubWhat("p/F"),
                    "p.D extends p.F (p.F implements p.I, FINAL public m), private m",
                    IllegalAccessError.class, "pD_ext_pF");
            // We'll take either a VerifyError (pre 2013-11-30)
            // or an IllegalAccessError (post 2013-11-22)
        } catch (VerifyError ve) {
            System.out.println("Saw expected VerifyError " + ve);
        }
        System.out.println();

        System.out.println("TRYING p.D.m PRIVATE interface-invoked as p.I.m, p.D extends p.E");
        tryAndCheckThrown(lt, bytesForDprivateSubWhat("p/E"),
                "p.D extends p.E (p.E implements p.I, public m), private m",
                IllegalAccessError.class, "pD_ext_pE");

        System.out.println("TRYING p.D.m ABSTRACT interface-invoked as p.I.m");
        tryAndCheckThrown(lt, bytesForD(),
                "D extends abstract C, no m",
                AbstractMethodError.class, "pD_ext_pC");

        System.out.println("TRYING q.D.m PACKAGE interface-invoked as p.I.m");
        tryAndCheckThrown(lt, "q.D", bytesForDsomeAccess("q/D", 0),
                "q.D implements p.I, protected m", IllegalAccessError.class,
                "qD_m_pp_imp_pI");

        // Note jar file name is used in the plural-arg case.
        System.out.println("TRYING p.D.m PRIVATE interface-invoked as p.I.m");
        tryAndCheckThrown(lt, bytesForDsomeAccess("p/D", ACC_PRIVATE),
                "p.D implements p.I, private m",
                IllegalAccessError.class, "pD_m_pri_imp_pI");

        // Plural-arg test.
        System.out.println("TRYING p.D.m PRIVATE MANY ARG interface-invoked as p.I.m");
        tryAndCheckThrownMany(lt, bytesForDsomeAccess("p/D", ACC_PRIVATE),
                "p.D implements p.I, private m", IllegalAccessError.class);

        if (lt.size() > 0) {
            System.out.flush();
            Thread.sleep(250); // This de-interleaves output and error in Netbeans, sigh.
            for (Throwable th : lt)
                System.err.println(th);
            throw new Error("Test failed, there were " + lt.size() + " failures listed above");
        } else {
            System.out.println("ALL PASS, HOORAY!");
        }
    }

    /**
     * The bytes for D, a NOT abstract class extending abstract class C without
     * supplying an implementation for abstract method m. There is a default
     * method in the interface I, but it should lose to the abstract class.
     *
     * @return
     * @throws Exception
     */
    public static byte[] bytesForD() throws Exception {

        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES
                | ClassWriter.COMPUTE_MAXS);
        MethodVisitor mv;

        cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, "p/D", null, "p/C", null);

        {
            mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
            mv.visitCode();
            mv.visitVarInsn(ALOAD, 0);
            mv.visitMethodInsn(INVOKESPECIAL, "p/C", "<init>", "()V");
            mv.visitInsn(RETURN);
            mv.visitMaxs(0, 0);
            mv.visitEnd();
        }
        cw.visitEnd();

        return cw.toByteArray();
    }

    /**
     * The bytes for D, implements I, does not extend C, declares m()I with
     * access method_acc.
     *
     * @param d_name Name of class defined
     * @param method_acc Accessibility of that class's method m.
     * @return
     * @throws Exception
     */
    public static byte[] bytesForDsomeAccess(String d_name, int method_acc) throws Exception {
        return bytesForSomeDsubSomethingSomeAccess(d_name, "java/lang/Object", method_acc);
    }

    /**
     * The bytes for D implements I, extends some class, declares m()I as
     * private.
     *
     * Invokeinterface of I.m applied to this D should throw IllegalAccessError
     *
     * @param sub_what The name of the class that D will extend.
     * @return
     * @throws Exception
     */
    public static byte[] bytesForDprivateSubWhat(String sub_what) throws Exception {
        return bytesForSomeDsubSomethingSomeAccess("p/D", sub_what, ACC_PRIVATE);
    }

    /**
     * Returns the bytes for a class with name d_name (presumably "D" in some
     * package), extending some class with name sub_what, implementing p.I,
     * and defining two methods m() and m(11args) with access method_acc.
     *
     * @param d_name      Name of class that is defined
     * @param sub_what    Name of class that it extends
     * @param method_acc  Accessibility of method(s) m in defined class.
     * @return
     * @throws Exception
     */
    public static byte[] bytesForSomeDsubSomethingSomeAccess
    (String d_name, String sub_what, int method_acc)
            throws Exception {

        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES
                | ClassWriter.COMPUTE_MAXS);
        MethodVisitor mv;
        String[] interfaces = {"p/I"};

        cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, d_name, null, sub_what, interfaces);
        {
            mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
            mv.visitCode();
            mv.visitVarInsn(ALOAD, 0);
            mv.visitMethodInsn(INVOKESPECIAL, sub_what, "<init>", "()V");
            mv.visitInsn(RETURN);
            mv.visitMaxs(0, 0);
            mv.visitEnd();
        }
        // int m() {return 3;}
        {
            mv = cw.visitMethod(method_acc, "m", "()I", null, null);
            mv.visitCode();
            mv.visitLdcInsn(new Integer(3));
            mv.visitInsn(IRETURN);
            mv.visitMaxs(0, 0);
            mv.visitEnd();
        }
        // int m(11args) {return 3;}
        {
            mv = cw.visitMethod(method_acc, "m", "(BCSIJ"
                    + "Ljava/lang/Object;"
                    + "Ljava/lang/Object;"
                    + "Ljava/lang/Object;"
                    + "Ljava/lang/Object;"
                    + "Ljava/lang/Object;"
                    + "Ljava/lang/Object;"
                    + ")I", null, null);
            mv.visitCode();
            mv.visitLdcInsn(new Integer(3));
            mv.visitInsn(IRETURN);
            mv.visitMaxs(0, 0);
            mv.visitEnd();
        }
        cw.visitEnd();
        return cw.toByteArray();
    }

    /**
     * The bytecodes for a class p/T defining a methods test() and test(11args)
     * that contain an invokeExact of a particular methodHandle, I.m.
     *
     * Test will be passed values that may imperfectly implement I,
     * and thus may in turn throw exceptions.
     *
     * @return
     * @throws Exception
     */
    public static byte[] bytesForT() throws Exception {

        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES
                | ClassWriter.COMPUTE_MAXS);
        MethodVisitor mv;

        cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, "p/T", null, "java/lang/Object", null);
        {
            mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
            mv.visitCode();
            mv.visitVarInsn(ALOAD, 0);
            mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
            mv.visitInsn(RETURN);
            mv.visitMaxs(0, 0);
            mv.visitEnd();
        }
        // static int test(I)
        {
            mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "test", "(Lp/I;)I", null, null);
            mv.visitCode();
            mv.visitLdcInsn(new Handle(Opcodes.H_INVOKEINTERFACE, "p/I", "m", "()I"));
            mv.visitVarInsn(ALOAD, 0);
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle",
                    "invokeExact", "(Lp/I;)I");
            mv.visitInsn(IRETURN);
            mv.visitMaxs(0, 0);
            mv.visitEnd();
        }
        // static int test(I,11args)
        {
            mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "test", "(Lp/I;BCSIJLjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)I", null, null);
            mv.visitCode();
            mv.visitLdcInsn(new Handle(Opcodes.H_INVOKEINTERFACE, "p/I", "m", "(BCSIJLjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)I"));
            mv.visitVarInsn(ALOAD, 0);
            mv.visitVarInsn(ILOAD, 1);
            mv.visitVarInsn(ILOAD, 2);
            mv.visitVarInsn(ILOAD, 3);
            mv.visitVarInsn(ILOAD, 4);
            mv.visitVarInsn(LLOAD, 5);
            mv.visitVarInsn(ALOAD, 7);
            mv.visitVarInsn(ALOAD, 8);
            mv.visitVarInsn(ALOAD, 9);
            mv.visitVarInsn(ALOAD, 10);
            mv.visitVarInsn(ALOAD, 11);
            mv.visitVarInsn(ALOAD, 12);
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle",
                    "invokeExact", "(Lp/I;BCSIJLjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)I");
            mv.visitInsn(IRETURN);
            mv.visitMaxs(0, 0);
            mv.visitEnd();
        }
        cw.visitEnd();
        return cw.toByteArray();
    }

    private static void tryAndCheckThrown(
            List<Throwable> lt, byte[] dBytes, String what, Class<?> expected, String jar_name)
            throws Throwable {
        tryAndCheckThrown(lt, "p.D", dBytes, what, expected, jar_name);
    }

    private static void tryAndCheckThrown(List<Throwable> lt, String d_name, byte[] dBytes, String what, Class<?> expected, String jar_name)
            throws Throwable {

        System.out.println("Methodhandle invokeExact I.m() for instance of " + what);
        ByteClassLoader bcl1 = new ByteClassLoader(jar_name, readJarFiles, writeJarFiles);
        try {
            Class<?> d1 = bcl1.loadBytes(d_name, dBytes);
            Class<?> t1 = bcl1.loadBytes("p.T", bytesForT());
            invokeTest(t1, d1, expected, lt);
        } finally {
            // Not necessary for others -- all class files are written in this call.
            // (unless the VM crashes first).
            bcl1.close();
        }

        System.out.println("Reflection invoke I.m() for instance of " + what);
        ByteClassLoader bcl3 = new ByteClassLoader(jar_name, readJarFiles, false);
        Class<?> d3 = bcl3.loadBytes(d_name, dBytes);
        Class<?> t3 = bcl3.loadClass("p.Treflect");
        invokeTest(t3, d3, expected, lt);

        System.out.println("Bytecode invokeInterface I.m() for instance of " + what);
        ByteClassLoader bcl2 = new ByteClassLoader(jar_name, readJarFiles, false);
        Class<?> d2 = bcl2.loadBytes(d_name, dBytes);
        Class<?> t2 = bcl2.loadClass("p.Tdirect");
        badGoodBadGood(t2, d2, expected, lt);
    }

    private static void invokeTest(Class<?> t, Class<?> d, Class<?> expected, List<Throwable> lt)
            throws Throwable {
        try {
            Method m = t.getMethod("test", p.I.class);
            Object o = d.newInstance();
            Object result = m.invoke(null, o);
            if (expected != null) {
                System.out.println("FAIL, Expected " + expected.getName()
                        + " wrapped in InvocationTargetException, but nothing was thrown");
                lt.add(new Error("Exception " + expected.getName() + " was not thrown"));
            } else {
                System.out.println("PASS, saw expected return.");
            }
        } catch (InvocationTargetException e) {
            Throwable th = e.getCause();
            th.printStackTrace(System.out);
            if (expected != null) {
                if (expected.isInstance(th)) {
                    System.out.println("PASS, saw expected exception (" + expected.getName() + ").");
                } else {
                    System.out.println("FAIL, Expected " + expected.getName()
                            + " wrapped in InvocationTargetException, saw " + th);
                    lt.add(th);
                }
            } else {
                System.out.println("FAIL, expected no exception, saw " + th);
                lt.add(th);
            }
        }
        System.out.println();
    }

    /* Many-arg versions of above */
    private static void tryAndCheckThrownMany(List<Throwable> lt, byte[] dBytes, String what, Class<?> expected)
            throws Throwable {

        System.out.println("Methodhandle invokeExact I.m(11params) for instance of " + what);
        ByteClassLoader bcl1 = new ByteClassLoader("p.D", readJarFiles, false);
        try {
            Class<?> d1 = bcl1.loadBytes("p.D", dBytes);
            Class<?> t1 = bcl1.loadBytes("p.T", bytesForT());
            invokeTestMany(t1, d1, expected, lt);
        } finally {
            bcl1.close(); // Not necessary for others -- all class files are written in this call.
        }

        {
            System.out.println("Bytecode invokeInterface I.m(11params) for instance of " + what);
            ByteClassLoader bcl2 = new ByteClassLoader("pD_m_pri_imp_pI", readJarFiles, false);
            Class<?> d2 = bcl2.loadBytes("p.D", dBytes);
            Class<?> t2 = bcl2.loadClass("p.Tdirect");
            badGoodBadGoodMany(t2, d2, expected, lt);

        }
        {
            System.out.println("Reflection invokeInterface I.m(11params) for instance of " + what);
            ByteClassLoader bcl2 = new ByteClassLoader("pD_m_pri_imp_pI", readJarFiles, false);
            Class<?> d2 = bcl2.loadBytes("p.D", dBytes);
            Class<?> t2 = bcl2.loadClass("p.Treflect");
            invokeTestMany(t2, d2, expected, lt);
        }
    }

    private static void invokeTestMany(Class<?> t, Class<?> d, Class<?> expected, List<Throwable> lt)
            throws Throwable {
        try {
            Method m = t.getMethod("test", p.I.class,
                    Byte.TYPE, Character.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE,
                    Object.class, Object.class, Object.class,
                    Object.class, Object.class, Object.class);
            Object o = d.newInstance();
            Byte b = 1;
            Character c = 2;
            Short s = 3;
            Integer i = 4;
            Long j = 5L;
            Object o1 = b;
            Object o2 = c;
            Object o3 = s;
            Object o4 = i;
            Object o5 = j;
            Object o6 = "6";

            Object result = m.invoke(null, o, b, c, s, i, j,
                    o1, o2, o3, o4, o5, o6);
            if (expected != null) {
                System.out.println("FAIL, Expected " + expected.getName()
                        + " wrapped in InvocationTargetException, but nothing was thrown");
                lt.add(new Error("Exception " + expected.getName()
                        + " was not thrown"));
            } else {
                System.out.println("PASS, saw expected return.");
            }
        } catch (InvocationTargetException e) {
            Throwable th = e.getCause();
            th.printStackTrace(System.out);
            if (expected != null) {
                if (expected.isInstance(th)) {
                    System.out.println("PASS, saw expected exception ("
                            + expected.getName() + ").");
                } else {
                    System.out.println("FAIL, Expected " + expected.getName()
                            + " wrapped in InvocationTargetException, saw " + th);
                    lt.add(th);
                }
            } else {
                System.out.println("FAIL, expected no exception, saw " + th);
                lt.add(th);
            }
        }
        System.out.println();
    }

    /**
     * This tests a peculiar idiom for tickling the bug on older VMs that lack
     * methodhandles.  The bug (if not fixed) acts in the following way:
     *
     *  When a broken receiver is passed to the first execution of an invokeinterface
     * bytecode, the illegal access is detected before the effects of resolution are
     * cached for later use, and so repeated calls with a broken receiver will always
     * throw the correct error.
     *
     * If, however, a good receiver is passed to the invokeinterface, the effects of
     * resolution will be successfully cached.  A subsequent execution with a broken
     * receiver will reuse the cached information, skip the detailed resolution work,
     * and instead encounter a null pointer.  By convention, that is the encoding for a
     * missing abstract method, and an AbstractMethodError is thrown -- not the expected
     * IllegalAccessError.
     *
     * @param t2 Test invocation class
     * @param d2 Test receiver class
     * @param expected expected exception type
     * @param lt list of unexpected throwables seen
     */
    private static void badGoodBadGood(Class<?> t2, Class<?> d2, Class<?> expected, List<Throwable> lt)
            throws Throwable {
        System.out.println("  Error input 1st time");
        invokeTest(t2, d2, expected, lt);
        System.out.println("  Good input (instance of Dok)");
        invokeTest(t2, Dok.class, null, lt);
        System.out.println("  Error input 2nd time");
        invokeTest(t2, d2, expected, lt);
        System.out.println("  Good input (instance of Dok)");
        invokeTest(t2, Dok.class, null, lt);
    }

    private static void badGoodBadGoodMany(Class<?> t2, Class<?> d2, Class<?> expected, List<Throwable> lt)
            throws Throwable {
        System.out.println("  Error input 1st time");
        invokeTestMany(t2, d2, expected, lt);
        System.out.println("  Good input (instance of Dok)");
        invokeTestMany(t2, Dok.class, null, lt);
        System.out.println("  Error input 2nd time");
        invokeTestMany(t2, d2, expected, lt);
        System.out.println("  Good input (instance of Dok)");
        invokeTestMany(t2, Dok.class, null, lt);
    }
}
