/***
 * ASM tests
 * Copyright (c) 2000-2011 INRIA, France Telecom
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the copyright holders nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.objectweb.asm;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;

import junit.framework.TestCase;

/**
 * ClassWriter unit tests for COMPUTE_MAXS option with JSR instructions.
 * 
 * @author Eric Bruneton
 */
public class ClassWriterComputeMaxsUnitTest extends TestCase {

    private Field successors;

    private Field successor;

    private Field succ;

    private Field next;

    protected ClassWriter cw;

    protected MethodVisitor mv;

    private Label start;

    @Override
    protected void setUp() throws Exception {
        Class<?> lClass = Label.class;
        Class<?> eClass = Edge.class;
        try {
            successors = lClass.getDeclaredField("successors");
            successor = lClass.getDeclaredField("successor");
            succ = eClass.getDeclaredField("successor");
            next = eClass.getDeclaredField("next");
        } catch (RuntimeException exception) {
            String f = "src/org/objectweb/asm/optimizer/shrink.properties";
            Properties p = new Properties();
            FileInputStream is = new FileInputStream(f);
            try {
                p.load(is);
            } finally {
                is.close();
            }
            String l = Type.getInternalName(lClass) + ".";
            String e = Type.getInternalName(eClass) + ".";
            successors = lClass.getDeclaredField(p
                    .getProperty(l + "successors"));
            successor = lClass.getDeclaredField(p.getProperty(l + "successor"));
            succ = eClass.getDeclaredField(p.getProperty(e + "successor"));
            next = eClass.getDeclaredField(p.getProperty(e + "next"));
        }
        cw = new ClassWriter(isComputeMaxs() ? ClassWriter.COMPUTE_MAXS : 0);
        cw.visit(Opcodes.V1_1, Opcodes.ACC_PUBLIC, "C", null,
                "java/lang/Object", null);
        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
        mv.visitCode();
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>",
                "()V");
        mv.visitInsn(Opcodes.RETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "m", "()V", null, null);
        mv.visitCode();
        start = new Label();
        LABEL(start);
    }

    protected boolean isComputeMaxs() {
        return true;
    }

    private void NOP() {
        mv.visitInsn(Opcodes.NOP);
    }

    private void PUSH() {
        mv.visitInsn(Opcodes.ICONST_0);
    }

    private void ICONST_0() {
        mv.visitInsn(Opcodes.ICONST_0);
    }

    private void ISTORE(final int var) {
        mv.visitVarInsn(Opcodes.ISTORE, var);
    }

    private void ALOAD(final int var) {
        mv.visitVarInsn(Opcodes.ALOAD, var);
    }

    private void ILOAD(final int var) {
        mv.visitVarInsn(Opcodes.ILOAD, var);
    }

    private void ASTORE(final int var) {
        mv.visitVarInsn(Opcodes.ASTORE, var);
    }

    private void RET(final int var) {
        mv.visitVarInsn(Opcodes.RET, var);
    }

    private void ATHROW() {
        mv.visitInsn(Opcodes.ATHROW);
    }

    private void ACONST_NULL() {
        mv.visitInsn(Opcodes.ACONST_NULL);
    }

    private void RETURN() {
        mv.visitInsn(Opcodes.RETURN);
    }

    private void LABEL(final Label l) {
        mv.visitLabel(l);
    }

    private void IINC(final int var, final int amnt) {
        mv.visitIincInsn(var, amnt);
    }

    private void GOTO(final Label l) {
        mv.visitJumpInsn(Opcodes.GOTO, l);
    }

    private void JSR(final Label l) {
        mv.visitJumpInsn(Opcodes.JSR, l);
    }

    private void IFNONNULL(final Label l) {
        mv.visitJumpInsn(Opcodes.IFNONNULL, l);
    }

    private void IFNE(final Label l) {
        mv.visitJumpInsn(Opcodes.IFNE, l);
    }

    private void TRYCATCH(final Label start, final Label end,
            final Label handler) {
        mv.visitTryCatchBlock(start, end, handler, null);
    }

    protected void assertMaxs(final int maxStack, final int maxLocals) {
        mv.visitMaxs(0, 0);
        mv.visitEnd();
        cw.visitEnd();
        byte[] b = cw.toByteArray();
        ClassReader cr = new ClassReader(b);
        cr.accept(new ClassVisitor(Opcodes.ASM4) {
            @Override
            public MethodVisitor visitMethod(final int access,
                    final String name, final String desc,
                    final String signature, final String[] exceptions) {
                if (name.equals("m")) {
                    return new MethodVisitor(Opcodes.ASM4) {
                        @Override
                        public void visitMaxs(final int realMaxStack,
                                final int realMaxLocals) {
                            assertEquals("maxStack", maxStack, realMaxStack);
                            assertEquals("maxLocals", maxLocals, realMaxLocals);
                        }
                    };
                } else {
                    return null;
                }
            }
        }, 0);

        try {
            TestClassLoader loader = new TestClassLoader();
            Class<?> c = loader.defineClass("C", b);
            c.newInstance();
        } catch (Throwable t) {
            fail(t.getMessage());
        }
    }

    protected void assertGraph(final String graph) {
        Map<String, Set<String>> expected = new HashMap<String, Set<String>>();
        Properties p = new Properties();
        try {
            p.load(new ByteArrayInputStream(graph.getBytes()));
        } catch (Exception e) {
            fail();
        }
        Iterator<Map.Entry<Object, Object>> i = p.entrySet().iterator();
        while (i.hasNext()) {
            Map.Entry<Object, Object> entry = i.next();
            String key = (String) entry.getKey();
            String value = (String) entry.getValue();
            StringTokenizer st = new StringTokenizer(value, ",");
            Set<String> s = new HashSet<String>();
            while (st.hasMoreTokens()) {
                s.add(st.nextToken());
            }
            expected.put(key, s);
        }

        Map<String, Set<String>> actual = new HashMap<String, Set<String>>();
        try {
            Label l = start;
            while (l != null) {
                String key = "N" + l.getOffset();
                Set<String> value = new HashSet<String>();
                Edge e = (Edge) successors.get(l);
                while (e != null) {
                    value.add("N" + ((Label) succ.get(e)).getOffset());
                    e = (Edge) next.get(e);
                }
                actual.put(key, value);
                l = (Label) successor.get(l);
            }
        } catch (IllegalAccessException e) {
            fail();
        }

        assertEquals(expected, actual);
    }

    protected static class TestClassLoader extends ClassLoader {

        public TestClassLoader() {
        }

        public Class<?> defineClass(final String name, final byte[] b) {
            return defineClass(name, b, 0, b.length);
        }
    }

    /**
     * Tests a method which has the most basic <code>try{}finally</code> form
     * imaginable:
     * 
     * <pre>
     * public void a() {
     *     int a = 0;
     *     try {
     *         a++;
     *     } finally {
     *         a--;
     *     }
     * }
     * </pre>
     */
    public void testBasic() {
        Label L0 = new Label();
        Label L1 = new Label();
        Label L2 = new Label();
        Label L3 = new Label();
        Label L4 = new Label();

        ICONST_0(); // N0
        ISTORE(1);

        /* L0: body of try block */
        LABEL(L0); // N2
        IINC(1, 1);
        GOTO(L1);

        /* L2: exception handler */
        LABEL(L2); // N8
        ASTORE(3);
        JSR(L3);
        ALOAD(3); // N12
        ATHROW();

        /* L3: subroutine */
        LABEL(L3); // N14
        ASTORE(2);
        IINC(1, -1);
        PUSH();
        PUSH();
        RET(2);

        /* L1: non-exceptional exit from try block */
        LABEL(L1); // N22
        JSR(L3);
        PUSH(); // N25
        PUSH();
        LABEL(L4); // N27
        RETURN();

        TRYCATCH(L0, L2, L2);
        TRYCATCH(L1, L4, L2);

        assertMaxs(4, 4);
        assertGraph("N0=N2\n" + "N2=N22,N8\n" + "N8=N14,N12\n" + "N12=\n"
                + "N14=N12,N25\n" + "N22=N14,N25,N8\n" + "N25=N27,N8\n"
                + "N27=\n");
    }

    /**
     * Tests a method which has an if/else-if w/in the finally clause:
     * 
     * <pre>
     * public void a() {
     *     int a = 0;
     *     try {
     *         a++;
     *     } finally {
     *         if (a == 0)
     *             a += 2;
     *         else
     *             a += 3;
     *     }
     * }
     * </pre>
     */
    public void testIfElseInFinally() {
        Label L0 = new Label();
        Label L1 = new Label();
        Label L2 = new Label();
        Label L3 = new Label();
        Label L4 = new Label();
        Label L5 = new Label();
        Label L6 = new Label();

        ICONST_0(); // N0
        ISTORE(1);

        /* L0: body of try block */
        LABEL(L0); // N2
        IINC(1, 1);
        GOTO(L1);

        /* L2: exception handler */
        LABEL(L2); // N8
        ASTORE(3);
        JSR(L3);
        PUSH(); // N12
        PUSH();
        ALOAD(3);
        ATHROW();

        /* L3: subroutine */
        LABEL(L3); // N16
        ASTORE(2);
        PUSH();
        PUSH();
        ILOAD(1);
        IFNE(L4);
        IINC(1, 2);
        GOTO(L5);

        LABEL(L4); // N29
        IINC(1, 3);

        LABEL(L5); // N32 common exit
        RET(2);

        /* L1: non-exceptional exit from try block */
        LABEL(L1); // N34
        JSR(L3);
        LABEL(L6); // N37
        RETURN();

        TRYCATCH(L0, L2, L2);
        TRYCATCH(L1, L6, L2);

        assertMaxs(5, 4);
        assertGraph("N0=N2\n" + "N2=N34,N8\n" + "N8=N16,N12\n" + "N12=\n"
                + "N16=N29,N32\n" + "N29=N32\n" + "N32=N37,N12\n"
                + "N34=N16,N37,N8\n" + "N37=\n");

    }

    /**
     * Tests a simple nested finally:
     * 
     * <pre>
     * public void a1() {
     *     int a = 0;
     *     try {
     *         a += 1;
     *     } finally {
     *         try {
     *             a += 2;
     *         } finally {
     *             a += 3;
     *         }
     *     }
     * }
     * </pre>
     */
    public void testSimpleNestedFinally() {
        Label L0 = new Label();
        Label L1 = new Label();
        Label L2 = new Label();
        Label L3 = new Label();
        Label L4 = new Label();
        Label L5 = new Label();

        ICONST_0(); // N0
        ISTORE(1);

        // L0: Body of try block:
        LABEL(L0); // N2
        IINC(1, 1);
        JSR(L3);
        GOTO(L1); // N8

        // L2: First exception handler:
        LABEL(L2); // N11
        ASTORE(4);
        JSR(L3);
        ALOAD(4); // N16
        ATHROW();

        // L3: First subroutine:
        LABEL(L3); // N19
        ASTORE(2);
        IINC(1, 2);
        JSR(L4);
        PUSH(); // N26
        PUSH();
        RET(2);

        // L5: Second exception handler:
        LABEL(L5); // N30
        ASTORE(5);
        JSR(L4);
        ALOAD(5); // N35
        ATHROW();

        // L4: Second subroutine:
        LABEL(L4); // N38
        ASTORE(3);
        PUSH();
        PUSH();
        IINC(1, 3);
        RET(3);

        // L1: On normal exit, try block jumps here:
        LABEL(L1); // N46
        RETURN();

        TRYCATCH(L0, L2, L2);
        TRYCATCH(L3, L5, L5);

        assertMaxs(5, 6);
        assertGraph("N0=N2\n" + "N2=N11,N19,N8\n" + "N8=N11,N46\n"
                + "N11=N19,N16\n" + "N16=\n" + "N19=N26,N30,N38\n"
                + "N26=N16,N30,N8\n" + "N30=N38,N35\n" + "N35=\n"
                + "N38=N26,N35\n" + "N46=\n");
    }

    /**
     * This tests a subroutine which has no ret statement, but ends in a
     * "return" instead.
     * 
     * We structure this as a try/finally with a break in the finally. Because
     * the while loop is infinite, it's clear from the byte code that the only
     * path which reaches the RETURN instruction is through the subroutine.
     * 
     * <pre>
     * public void a1() {
     *     int a = 0;
     *     while (true) {
     *         try {
     *             a += 1;
     *         } finally {
     *             a += 2;
     *             break;
     *         }
     *     }
     * }
     * </pre>
     */
    public void testSubroutineWithNoRet() {
        Label L0 = new Label();
        Label L1 = new Label();
        Label L2 = new Label();
        Label L3 = new Label();
        Label L4 = new Label();

        ICONST_0(); // N0
        ISTORE(1);

        // L0: while loop header/try block
        LABEL(L0); // N2
        IINC(1, 1);
        JSR(L1);
        GOTO(L2); // N8

        // L3: implicit catch block
        LABEL(L3); // N11
        ASTORE(2);
        JSR(L1);
        PUSH(); // N15
        PUSH();
        ALOAD(2);
        ATHROW();

        // L1: subroutine ...
        LABEL(L1); // N19
        ASTORE(3);
        IINC(1, 2);
        GOTO(L4); // ...not that it does not return!

        // L2: end of the loop... goes back to the top!
        LABEL(L2); // N26
        GOTO(L0);

        // L4:
        LABEL(L4); // N29
        RETURN();

        TRYCATCH(L0, L3, L3);

        assertMaxs(1, 4);
        assertGraph("N0=N2\n" + "N2=N11,N19,N8\n" + "N8=N11,N26\n"
                + "N11=N19,N15\n" + "N15=\n" + "N19=N29\n" + "N26=N2\n"
                + "N29=\n");
    }

    /**
     * This tests a subroutine which has no ret statement, but ends in a
     * "return" instead.
     * 
     * <pre>
     *   ACONST_NULL
     *   JSR L0
     * L0:
     *   ASTORE 0
     *   ASTORE 0
     *   RETURN
     * </pre>
     */
    public void testSubroutineWithNoRet2() {
        Label L0 = new Label();
        Label L1 = new Label();

        ACONST_NULL(); // N0
        JSR(L0);
        NOP(); // N4
        LABEL(L0); // N5
        ASTORE(0);
        ASTORE(0);
        RETURN();
        LABEL(L1); // N8
        mv.visitLocalVariable("i", "I", null, L0, L1, 1);

        assertMaxs(2, 2);
        assertGraph("N0=N4,N5\n" + "N4=N5\n" + "N5=\n" + "N8=\n");
    }

    /**
     * This tests a subroutine which has no ret statement, but instead exits
     * implicitely by branching to code which is not part of the subroutine.
     * (Sadly, this is legal)
     * 
     * We structure this as a try/finally in a loop with a break in the finally.
     * The loop is not trivially infinite, so the RETURN statement is reachable
     * both from the JSR subroutine and from the main entry point.
     * 
     * <pre>
     * public void a1() {
     *     int a = 0;
     *     while (null == null) {
     *         try {
     *             a += 1;
     *         } finally {
     *             a += 2;
     *             break;
     *         }
     *     }
     * }
     * </pre>
     */
    public void testImplicitExit() {
        Label L0 = new Label();
        Label L1 = new Label();
        Label L2 = new Label();
        Label L3 = new Label();
        Label L4 = new Label();
        Label L5 = new Label();

        ICONST_0(); // N0
        ISTORE(1);

        // L5: while loop header
        LABEL(L5); // N2
        ACONST_NULL();
        IFNONNULL(L4);

        // L0: try block
        LABEL(L0); // N6
        IINC(1, 1);
        JSR(L1);
        GOTO(L2); // N12

        // L3: implicit catch block
        LABEL(L3); // N15
        ASTORE(2);
        JSR(L1);
        ALOAD(2); // N19
        PUSH();
        PUSH();
        ATHROW();

        // L1: subroutine ...
        LABEL(L1); // N23
        ASTORE(3);
        IINC(1, 2);
        GOTO(L4); // ...not that it does not return!

        // L2: end of the loop... goes back to the top!
        LABEL(L2); // N30
        GOTO(L0);

        // L4:
        LABEL(L4); // N33
        RETURN();

        TRYCATCH(L0, L3, L3);

        assertMaxs(1, 4);
        assertGraph("N0=N2\n" + "N2=N6,N33\n" + "N6=N23,N12,N15\n"
                + "N12=N30,N15\n" + "N15=N23,N19\n" + "N19=\n" + "N23=N33\n"
                + "N30=N6\n" + "N33=\n");
    }

    /**
     * Tests a nested try/finally with implicit exit from one subroutine to the
     * other subroutine. Equivalent to the following java code:
     * 
     * <pre>
     * void m(boolean b) {
     *     try {
     *         return;
     *     } finally {
     *         while (b) {
     *             try {
     *                 return;
     *             } finally {
     *                 // NOTE --- this break avoids the second return above (weird)
     *                 if (b)
     *                     break;
     *             }
     *         }
     *     }
     * }
     * </pre>
     * 
     * This example is from the paper, "Subroutine Inlining and Bytecode
     * Abstraction to Simplify Static and Dynamic Analysis" by Cyrille Artho and
     * Armin Biere.
     */
    public void testImplicitExitToAnotherSubroutine() {
        Label T1 = new Label();
        Label C1 = new Label();
        Label S1 = new Label();
        Label L = new Label();
        Label C2 = new Label();
        Label S2 = new Label();
        Label W = new Label();
        Label X = new Label();

        // variable numbers:
        int b = 1;
        int e1 = 2;
        int e2 = 3;
        int r1 = 4;
        int r2 = 5;

        ICONST_0(); // N0
        ISTORE(1);

        // T1: first try:
        LABEL(T1); // N2
        JSR(S1);
        RETURN(); // N5

        // C1: exception handler for first try
        LABEL(C1); // N6
        ASTORE(e1);
        JSR(S1);
        PUSH(); // N10
        PUSH();
        ALOAD(e1);
        ATHROW();

        // S1: first finally handler
        LABEL(S1); // N14
        ASTORE(r1);
        PUSH();
        PUSH();
        GOTO(W);

        // L: body of while loop, also second try
        LABEL(L); // N21
        JSR(S2);
        RETURN(); // N24

        // C2: exception handler for second try
        LABEL(C2); // N25
        ASTORE(e2);
        PUSH();
        PUSH();
        JSR(S2);
        ALOAD(e2); // N31
        ATHROW();

        // S2: second finally handler
        LABEL(S2); // N33
        ASTORE(r2);
        ILOAD(b);
        IFNE(X);
        RET(r2);

        // W: test for the while loop
        LABEL(W); // N41
        ILOAD(b);
        IFNE(L); // falls through to X

        // X: exit from finally{} block
        LABEL(X); // N45
        RET(r1);

        TRYCATCH(T1, C1, C1);
        TRYCATCH(L, C2, C2);

        assertMaxs(5, 6);
        assertGraph("N0=N2\n" + "N2=N6,N5,N14\n" + "N5=N6\n" + "N6=N14,N10\n"
                + "N10=\n" + "N14=N41\n" + "N21=N24,N25,N33\n" + "N24=N25\n"
                + "N25=N31,N33\n" + "N31=\n" + "N33=N31,N45,N24\n"
                + "N41=N45,N21\n" + "N45=N5,N10\n");
    }

    public void testImplicitExitToAnotherSubroutine2() {
        Label L1 = new Label();
        Label L2 = new Label();
        Label L3 = new Label();

        ICONST_0(); // N0
        ISTORE(1);
        JSR(L1);
        RETURN(); // N5

        LABEL(L1); // N6
        ASTORE(2);
        JSR(L2);
        GOTO(L3); // N10

        LABEL(L2); // N13
        ASTORE(3);
        ILOAD(1);
        IFNE(L3);
        RET(3);

        LABEL(L3); // N20
        RET(2);

        assertMaxs(1, 4);
        assertGraph("N0=N6,N5\n" + "N5=\n" + "N6=N10,N13\n" + "N10=N20\n"
                + "N13=N20,N10\n" + "N20=N5\n");
    }

    /**
     * This tests a simple subroutine where the control flow jumps back and
     * forth between the subroutine and the caller.
     * 
     * This would not normally be produced by a java compiler.
     */
    public void testInterleavedCode() {
        Label L1 = new Label();
        Label L2 = new Label();
        Label L3 = new Label();
        Label L4 = new Label();

        ICONST_0(); // N0
        ISTORE(1);
        JSR(L1);
        GOTO(L2); // N5

        // L1: subroutine 1
        LABEL(L1); // N8
        ASTORE(2);
        IINC(1, 1);
        GOTO(L3);

        // L2: second part of main subroutine
        LABEL(L2); // N15
        IINC(1, 2);
        GOTO(L4);

        // L3: second part of subroutine 1
        LABEL(L3); // N21
        IINC(1, 4);
        PUSH();
        PUSH();
        RET(2);

        // L4: third part of main subroutine
        LABEL(L4); // N28
        PUSH();
        PUSH();
        RETURN();

        assertMaxs(4, 3);
        assertGraph("N0=N5,N8\n" + "N5=N15\n" + "N8=N21\n" + "N15=N28\n"
                + "N21=N5\n" + "N28=\n");
    }

    /**
     * Tests a nested try/finally with implicit exit from one subroutine to the
     * other subroutine, and with a surrounding try/catch thrown in the mix.
     * Equivalent to the following java code:
     * 
     * <pre>
     * void m(int b) {
     *     try {
     *         try {
     *             return;
     *         } finally {
     *             while (b) {
     *                 try {
     *                     return;
     *                 } finally {
     *                     // NOTE --- this break avoids the second return above
     *                     // (weird)
     *                     if (b)
     *                         break;
     *                 }
     *             }
     *         }
     *     } catch (Exception e) {
     *         b += 3;
     *         return;
     *     }
     * }
     * </pre>
     */
    public void testImplicitExitInTryCatch() {
        Label T1 = new Label();
        Label C1 = new Label();
        Label S1 = new Label();
        Label L = new Label();
        Label C2 = new Label();
        Label S2 = new Label();
        Label W = new Label();
        Label X = new Label();
        Label OC = new Label();

        // variable numbers:
        int b = 1;
        int e1 = 2;
        int e2 = 3;
        int r1 = 4;
        int r2 = 5;

        ICONST_0(); // N0
        ISTORE(1);

        // T1: first try:
        LABEL(T1); // N2
        JSR(S1);
        RETURN(); // N5

        // C1: exception handler for first try
        LABEL(C1); // N6
        ASTORE(e1);
        JSR(S1);
        ALOAD(e1); // N10
        ATHROW();

        // S1: first finally handler
        LABEL(S1); // N12
        ASTORE(r1);
        GOTO(W);

        // L: body of while loop, also second try
        LABEL(L); // N17
        JSR(S2);
        PUSH(); // N20
        PUSH();
        RETURN();

        // C2: exception handler for second try
        LABEL(C2); // N23
        ASTORE(e2);
        JSR(S2);
        ALOAD(e2); // N27
        ATHROW();

        // S2: second finally handler
        LABEL(S2); // N29
        ASTORE(r2);
        ILOAD(b);
        IFNE(X);
        PUSH();
        PUSH();
        RET(r2);

        // W: test for the while loop
        LABEL(W); // N39
        ILOAD(b);
        IFNE(L); // falls through to X

        // X: exit from finally{} block
        LABEL(X); // N43
        RET(r1);

        // OC: outermost catch
        LABEL(OC); // N45
        IINC(b, 3);
        RETURN();

        TRYCATCH(T1, C1, C1);
        TRYCATCH(L, C2, C2);
        TRYCATCH(T1, OC, OC);

        assertMaxs(4, 6);
        assertGraph("N0=N2\n" + "N2=N6,N45,N5,N12\n" + "N5=N6,N45\n"
                + "N6=N45,N12,N10\n" + "N10=N45\n" + "N12=N39,N45\n"
                + "N17=N23,N45,N20,N29\n" + "N20=N23,N45\n"
                + "N23=N45,N27,N29\n" + "N27=N45\n" + "N29=N43,N45,N20,N27\n"
                + "N39=N43,N45,N17\n" + "N43=N45,N5,N10\n" + "N45=\n");
    }
}
