/*
 * Copyright (c) 2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */


/**
 * @test
 * @bug 6547378
 * @summary Verify that methods with max_stack==0 don't have exception handlers
 * @author Keith McGuigan
 */

public class VerifyStackForExceptionHandlers extends ClassLoader {
    public static void main(String argv[]) throws Exception {
        VerifyStackForExceptionHandlers t =
            new VerifyStackForExceptionHandlers();

        try {
            t.loadGoodClass();
        } catch(VerifyError e) {
            throw new Exception("FAIL: should be no VerifyError for class A");
        }

        try {
            t.loadBadClass();
            throw new Exception("FAIL: should be a VerifyError for class B");
        } catch(VerifyError e) {
            System.out.println("PASS");
        }
    }

    private void loadGoodClass() {
        /* -- code for class A --
           public class A {
               public static void f() {}
           }
        */
        long[] cls_data = {
            0xcafebabe00000031L, 0x000e0a0003000b07L,
            0x000c07000d010006L, 0x3c696e69743e0100L,
            0x0328295601000443L, 0x6f646501000f4c69L,
            0x6e654e756d626572L, 0x5461626c65010001L,
            0x6601000a536f7572L, 0x636546696c650100L,
            0x06412e6a6176610cL, 0x0004000501000141L,
            0x0100106a6176612fL, 0x6c616e672f4f626aL,
            0x6563740021000200L, 0x0300000000000200L,
            0x0100040005000100L, 0x060000001d000100L,
            0x01000000052ab700L, 0x01b1000000010007L,
            0x0000000600010000L, 0x0001000900080005L,
            0x0001000600000019L, 0x0000000000000001L,
            0xb100000001000700L, 0x0000060001000000L,
            0x0200010009000000L, 0x02000a0000000000L
        };
        final int EXTRA = 5;

        byte cf_bytes[] = toByteArray(cls_data);
        Class c = defineClass("A", cf_bytes, 0, cf_bytes.length - EXTRA);

        try { c.newInstance(); } // to force linking, thus verification
        catch(InstantiationException e) {}
        catch(IllegalAccessException e) {}
    }

    private void loadBadClass() throws VerifyError {
        /* -- code for class B --
           public class B {
               public static void g() {}
               public static void f() {
                  // bytecode modified to have a max_stack value of 0
                  try { g(); }
                  catch (NullPointerException e) {}
               }
        }
        */
        long[] cls_data = {
            0xcafebabe00000031L, 0x00120a000400060aL,
            0x000d00030c000f00L, 0x0a0700050100106aL,
            0x6176612f6c616e67L, 0x2f4f626a6563740cL,
            0x0011000a01000a53L, 0x6f7572636546696cL,
            0x6507000901001e6aL, 0x6176612f6c616e67L,
            0x2f4e756c6c506f69L, 0x6e74657245786365L,
            0x7074696f6e010003L, 0x282956010006422eL,
            0x6a61736d01000443L, 0x6f646507000e0100L,
            0x0142010001670100L, 0x01660100063c696eL,
            0x69743e0021000d00L, 0x0400000000000300L,
            0x010011000a000100L, 0x0c00000011000100L,
            0x01000000052ab700L, 0x01b1000000000009L,
            0x000f000a0001000cL, 0x0000000d00000000L,
            0x00000001b1000000L, 0x0000090010000a00L,
            0x01000c0000001c00L, 0x00000100000008b8L,
            0x0002a700044bb100L, 0x0100000003000600L,
            0x0800000001000700L, 0x000002000b000000L // 3 bytes extra

        };
        final int EXTRA = 3;

        byte cf_bytes[] = toByteArray(cls_data);
        Class c = defineClass("B", cf_bytes, 0, cf_bytes.length - EXTRA);

        try { c.newInstance(); } // to force linking, thus verification
        catch(InstantiationException e) {}
        catch(IllegalAccessException e) {}
    }

    static private byte[] toByteArray(long arr[]) {
        // convert long array to byte array
        java.nio.ByteBuffer bbuf = java.nio.ByteBuffer.allocate(arr.length * 8);
        bbuf.asLongBuffer().put(java.nio.LongBuffer.wrap(arr));
        return bbuf.array();
    }
    }
