/***
 * ASM: a very small and fast Java bytecode manipulation framework
 * Copyright (c) 2000-2007 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.eclipse.persistence.internal.libraries.asm.tree;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.eclipse.persistence.internal.libraries.asm.MethodVisitor;
import org.eclipse.persistence.internal.libraries.asm.Opcodes;

/**
 * A node that represents a stack map frame. These nodes are pseudo instruction
 * nodes in order to be inserted in an instruction list. In fact these nodes
 * must(*) be inserted <i>just before</i> any instruction node <b>i</b> that
 * follows an unconditionnal branch instruction such as GOTO or THROW, that is
 * the target of a jump instruction, or that starts an exception handler block.
 * The stack map frame types must describe the values of the local variables and
 * of the operand stack elements <i>just before</i> <b>i</b> is executed. <br>
 * <br> (*) this is mandatory only for classes whose version is greater than or
 * equal to {@link Opcodes#V1_6 V1_6}.
 * 
 * @author Eric Bruneton
 */
public class FrameNode extends AbstractInsnNode {

    /**
     * The type of this frame. Must be {@link Opcodes#F_NEW} for expanded
     * frames, or {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND},
     * {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or
     * {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for compressed frames.
     */
    public int type;

    /**
     * The types of the local variables of this stack map frame. Elements of
     * this list can be Integer, String or LabelNode objects (for primitive,
     * reference and uninitialized types respectively - see
     * {@link MethodVisitor}).
     */
    public List local;

    /**
     * The types of the operand stack elements of this stack map frame. Elements
     * of this list can be Integer, String or LabelNode objects (for primitive,
     * reference and uninitialized types respectively - see
     * {@link MethodVisitor}).
     */
    public List stack;

    private FrameNode() {
        super(-1);
    }

    /**
     * Constructs a new {@link FrameNode}.
     * 
     * @param type the type of this frame. Must be {@link Opcodes#F_NEW} for
     *        expanded frames, or {@link Opcodes#F_FULL},
     *        {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP},
     *        {@link Opcodes#F_SAME} or {@link Opcodes#F_APPEND},
     *        {@link Opcodes#F_SAME1} for compressed frames.
     * @param nLocal number of local variables of this stack map frame.
     * @param local the types of the local variables of this stack map frame.
     *        Elements of this list can be Integer, String or LabelNode objects
     *        (for primitive, reference and uninitialized types respectively -
     *        see {@link MethodVisitor}).
     * @param nStack number of operand stack elements of this stack map frame.
     * @param stack the types of the operand stack elements of this stack map
     *        frame. Elements of this list can be Integer, String or LabelNode
     *        objects (for primitive, reference and uninitialized types
     *        respectively - see {@link MethodVisitor}).
     */
    public FrameNode(
        final int type,
        final int nLocal,
        final Object[] local,
        final int nStack,
        final Object[] stack)
    {
        super(-1);
        this.type = type;
        switch (type) {
            case Opcodes.F_NEW:
            case Opcodes.F_FULL:
                this.local = asList(nLocal, local);
                this.stack = asList(nStack, stack);
                break;
            case Opcodes.F_APPEND:
                this.local = asList(nLocal, local);
                break;
            case Opcodes.F_CHOP:
                this.local = Arrays.asList(new Object[nLocal]);
                break;
            case Opcodes.F_SAME:
                break;
            case Opcodes.F_SAME1:
                this.stack = asList(1, stack);
                break;
        }
    }

    public int getType() {
        return FRAME;
    }

    /**
     * Makes the given visitor visit this stack map frame.
     * 
     * @param mv a method visitor.
     */
    public void accept(final MethodVisitor mv) {
        switch (type) {
            case Opcodes.F_NEW:
            case Opcodes.F_FULL:
                mv.visitFrame(type,
                        local.size(),
                        asArray(local),
                        stack.size(),
                        asArray(stack));
                break;
            case Opcodes.F_APPEND:
                mv.visitFrame(type, local.size(), asArray(local), 0, null);
                break;
            case Opcodes.F_CHOP:
                mv.visitFrame(type, local.size(), null, 0, null);
                break;
            case Opcodes.F_SAME:
                mv.visitFrame(type, 0, null, 0, null);
                break;
            case Opcodes.F_SAME1:
                mv.visitFrame(type, 0, null, 1, asArray(stack));
                break;
        }
    }

    public AbstractInsnNode clone(final Map labels) {
        FrameNode clone = new FrameNode();
        clone.type = type;
        if (local != null) {
            clone.local = new ArrayList();
            for (int i = 0; i < local.size(); ++i) {
                Object l = local.get(i);
                if (l instanceof LabelNode) {
                    l = labels.get(l);
                }
                clone.local.add(l);
            }
        }
        if (stack != null) {
            clone.stack = new ArrayList();
            for (int i = 0; i < stack.size(); ++i) {
                Object s = stack.get(i);
                if (s instanceof LabelNode) {
                    s = labels.get(s);
                }
                clone.stack.add(s);
            }
        }
        return clone;
    }

    // ------------------------------------------------------------------------

    private static List asList(final int n, final Object[] o) {
        return Arrays.asList(o).subList(0, n);
    }

    private static Object[] asArray(final List l) {
        Object[] objs = new Object[l.size()];
        for (int i = 0; i < objs.length; ++i) {
            Object o = l.get(i);
            if (o instanceof LabelNode) {
                o = ((LabelNode) o).getLabel();
            }
            objs[i] = o;
        }
        return objs;
    }
}
