/*
 * Copyright (c) 2001, 2004, 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * 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.
 */

package sun.reflect;

class ClassFileAssembler implements ClassFileConstants {
    private ByteVector vec;
    private short cpIdx = 0;

    public ClassFileAssembler() {
        this(ByteVectorFactory.create());
    }

    public ClassFileAssembler(ByteVector vec) {
        this.vec = vec;
    }

    public ByteVector getData() {
        return vec;
    }

    /** Length in bytes */
    public short getLength() {
        return (short) vec.getLength();
    }

    public void emitMagicAndVersion() {
        emitInt(0xCAFEBABE);
        emitShort((short) 0);
        emitShort((short) 49);
    }

    public void emitInt(int val) {
        emitByte((byte) (val >> 24));
        emitByte((byte) ((val >> 16) & 0xFF));
        emitByte((byte) ((val >> 8) & 0xFF));
        emitByte((byte) (val & 0xFF));
    }

    public void emitShort(short val) {
        emitByte((byte) ((val >> 8) & 0xFF));
        emitByte((byte) (val & 0xFF));
    }

    // Support for labels; package-private
    void emitShort(short bci, short val) {
        vec.put(bci,     (byte) ((val >> 8) & 0xFF));
        vec.put(bci + 1, (byte) (val & 0xFF));
    }

    public void emitByte(byte val) {
        vec.add(val);
    }

    public void append(ClassFileAssembler asm) {
        append(asm.vec);
    }

    public void append(ByteVector vec) {
        for (int i = 0; i < vec.getLength(); i++) {
            emitByte(vec.get(i));
        }
    }

    /** Keeps track of the current (one-based) constant pool index;
        incremented after emitting one of the following constant pool
        entries. Can fetch the current constant pool index for use in
        later entries.  Index points at the last valid constant pool
        entry; initially invalid. It is illegal to fetch the constant
        pool index before emitting at least one constant pool entry. */
    public short cpi() {
        if (cpIdx == 0) {
            throw new RuntimeException("Illegal use of ClassFileAssembler");
        }
        return cpIdx;
    }

    public void emitConstantPoolUTF8(String str) {
        // NOTE: can not use str.getBytes("UTF-8") here because of
        // bootstrapping issues with the character set converters.
        byte[] bytes = UTF8.encode(str);
        emitByte(CONSTANT_Utf8);
        emitShort((short) bytes.length);
        for (int i = 0; i < bytes.length; i++) {
            emitByte(bytes[i]);
        }
        cpIdx++;
    }

    public void emitConstantPoolClass(short index) {
        emitByte(CONSTANT_Class);
        emitShort(index);
        cpIdx++;
    }

    public void emitConstantPoolNameAndType(short nameIndex, short typeIndex) {
        emitByte(CONSTANT_NameAndType);
        emitShort(nameIndex);
        emitShort(typeIndex);
        cpIdx++;
    }

    public void emitConstantPoolFieldref
        (short classIndex, short nameAndTypeIndex)
    {
        emitByte(CONSTANT_Fieldref);
        emitShort(classIndex);
        emitShort(nameAndTypeIndex);
        cpIdx++;
    }

    public void emitConstantPoolMethodref
        (short classIndex, short nameAndTypeIndex)
    {
        emitByte(CONSTANT_Methodref);
        emitShort(classIndex);
        emitShort(nameAndTypeIndex);
        cpIdx++;
    }

    public void emitConstantPoolInterfaceMethodref
        (short classIndex, short nameAndTypeIndex)
    {
        emitByte(CONSTANT_InterfaceMethodref);
        emitShort(classIndex);
        emitShort(nameAndTypeIndex);
        cpIdx++;
    }

    public void emitConstantPoolString(short utf8Index) {
        emitByte(CONSTANT_String);
        emitShort(utf8Index);
        cpIdx++;
    }

    //----------------------------------------------------------------------
    // Opcodes. Keeps track of maximum stack and locals. Make a new
    // assembler for each piece of assembled code, then append the
    // result to the previous assembler's class file.
    //

    private int stack     = 0;
    private int maxStack  = 0;
    private int maxLocals = 0;

    private void incStack() {
        setStack(stack + 1);
    }

    private void decStack() {
        --stack;
    }

    public short getMaxStack() {
        return (short) maxStack;
    }

    public short getMaxLocals() {
        return (short) maxLocals;
    }

    /** It's necessary to be able to specify the number of arguments at
        the beginning of the method (which translates to the initial
        value of max locals) */
    public void setMaxLocals(int maxLocals) {
        this.maxLocals = maxLocals;
    }

    /** Needed to do flow control. Returns current stack depth. */
    public int getStack() {
        return stack;
    }

    /** Needed to do flow control. */
    public void setStack(int value) {
        stack = value;
        if (stack > maxStack) {
            maxStack = stack;
        }
    }

    ///////////////
    // Constants //
    ///////////////

    public void opc_aconst_null() {
        emitByte(opc_aconst_null);
        incStack();
    }

    public void opc_sipush(short constant) {
        emitByte(opc_sipush);
        emitShort(constant);
        incStack();
    }

    public void opc_ldc(byte cpIdx) {
        emitByte(opc_ldc);
        emitByte(cpIdx);
        incStack();
    }

    /////////////////////////////////////
    // Local variable loads and stores //
    /////////////////////////////////////

    public void opc_iload_0() {
        emitByte(opc_iload_0);
        if (maxLocals < 1) maxLocals = 1;
        incStack();
    }

    public void opc_iload_1() {
        emitByte(opc_iload_1);
        if (maxLocals < 2) maxLocals = 2;
        incStack();
    }

    public void opc_iload_2() {
        emitByte(opc_iload_2);
        if (maxLocals < 3) maxLocals = 3;
        incStack();
    }

    public void opc_iload_3() {
        emitByte(opc_iload_3);
        if (maxLocals < 4) maxLocals = 4;
        incStack();
    }

    public void opc_lload_0() {
        emitByte(opc_lload_0);
        if (maxLocals < 2) maxLocals = 2;
        incStack();
        incStack();
    }

    public void opc_lload_1() {
        emitByte(opc_lload_1);
        if (maxLocals < 3) maxLocals = 3;
        incStack();
        incStack();
    }

    public void opc_lload_2() {
        emitByte(opc_lload_2);
        if (maxLocals < 4) maxLocals = 4;
        incStack();
        incStack();
    }

    public void opc_lload_3() {
        emitByte(opc_lload_3);
        if (maxLocals < 5) maxLocals = 5;
        incStack();
        incStack();
    }

    public void opc_fload_0() {
        emitByte(opc_fload_0);
        if (maxLocals < 1) maxLocals = 1;
        incStack();
    }

    public void opc_fload_1() {
        emitByte(opc_fload_1);
        if (maxLocals < 2) maxLocals = 2;
        incStack();
    }

    public void opc_fload_2() {
        emitByte(opc_fload_2);
        if (maxLocals < 3) maxLocals = 3;
        incStack();
    }

    public void opc_fload_3() {
        emitByte(opc_fload_3);
        if (maxLocals < 4) maxLocals = 4;
        incStack();
    }

    public void opc_dload_0() {
        emitByte(opc_dload_0);
        if (maxLocals < 2) maxLocals = 2;
        incStack();
        incStack();
    }

    public void opc_dload_1() {
        emitByte(opc_dload_1);
        if (maxLocals < 3) maxLocals = 3;
        incStack();
        incStack();
    }

    public void opc_dload_2() {
        emitByte(opc_dload_2);
        if (maxLocals < 4) maxLocals = 4;
        incStack();
        incStack();
    }

    public void opc_dload_3() {
        emitByte(opc_dload_3);
        if (maxLocals < 5) maxLocals = 5;
        incStack();
        incStack();
    }

    public void opc_aload_0() {
        emitByte(opc_aload_0);
        if (maxLocals < 1) maxLocals = 1;
        incStack();
    }

    public void opc_aload_1() {
        emitByte(opc_aload_1);
        if (maxLocals < 2) maxLocals = 2;
        incStack();
    }

    public void opc_aload_2() {
        emitByte(opc_aload_2);
        if (maxLocals < 3) maxLocals = 3;
        incStack();
    }

    public void opc_aload_3() {
        emitByte(opc_aload_3);
        if (maxLocals < 4) maxLocals = 4;
        incStack();
    }

    public void opc_aaload() {
        emitByte(opc_aaload);
        decStack();
    }

    public void opc_astore_0() {
        emitByte(opc_astore_0);
        if (maxLocals < 1) maxLocals = 1;
        decStack();
    }

    public void opc_astore_1() {
        emitByte(opc_astore_1);
        if (maxLocals < 2) maxLocals = 2;
        decStack();
    }

    public void opc_astore_2() {
        emitByte(opc_astore_2);
        if (maxLocals < 3) maxLocals = 3;
        decStack();
    }

    public void opc_astore_3() {
        emitByte(opc_astore_3);
        if (maxLocals < 4) maxLocals = 4;
        decStack();
    }

    ////////////////////////
    // Stack manipulation //
    ////////////////////////

    public void opc_pop() {
        emitByte(opc_pop);
        decStack();
    }

    public void opc_dup() {
        emitByte(opc_dup);
        incStack();
    }

    public void opc_dup_x1() {
        emitByte(opc_dup_x1);
        incStack();
    }

    public void opc_swap() {
        emitByte(opc_swap);
    }

    ///////////////////////////////
    // Widening conversions only //
    ///////////////////////////////

    public void opc_i2l() {
        emitByte(opc_i2l);
    }

    public void opc_i2f() {
        emitByte(opc_i2f);
    }

    public void opc_i2d() {
        emitByte(opc_i2d);
    }

    public void opc_l2f() {
        emitByte(opc_l2f);
    }

    public void opc_l2d() {
        emitByte(opc_l2d);
    }

    public void opc_f2d() {
        emitByte(opc_f2d);
    }

    //////////////////
    // Control flow //
    //////////////////

    public void opc_ifeq(short bciOffset) {
        emitByte(opc_ifeq);
        emitShort(bciOffset);
        decStack();
    }

    /** Control flow with forward-reference BCI. Stack assumes
        straight-through control flow. */
    public void opc_ifeq(Label l) {
        short instrBCI = getLength();
        emitByte(opc_ifeq);
        l.add(this, instrBCI, getLength(), getStack() - 1);
        emitShort((short) -1); // Must be patched later
    }

    public void opc_if_icmpeq(short bciOffset) {
        emitByte(opc_if_icmpeq);
        emitShort(bciOffset);
        setStack(getStack() - 2);
    }

    /** Control flow with forward-reference BCI. Stack assumes straight
        control flow. */
    public void opc_if_icmpeq(Label l) {
        short instrBCI = getLength();
        emitByte(opc_if_icmpeq);
        l.add(this, instrBCI, getLength(), getStack() - 2);
        emitShort((short) -1); // Must be patched later
    }

    public void opc_goto(short bciOffset) {
        emitByte(opc_goto);
        emitShort(bciOffset);
    }

    /** Control flow with forward-reference BCI. Stack assumes straight
        control flow. */
    public void opc_goto(Label l) {
        short instrBCI = getLength();
        emitByte(opc_goto);
        l.add(this, instrBCI, getLength(), getStack());
        emitShort((short) -1); // Must be patched later
    }

    public void opc_ifnull(short bciOffset) {
        emitByte(opc_ifnull);
        emitShort(bciOffset);
        decStack();
    }

    /** Control flow with forward-reference BCI. Stack assumes straight
        control flow. */
    public void opc_ifnull(Label l) {
        short instrBCI = getLength();
        emitByte(opc_ifnull);
        l.add(this, instrBCI, getLength(), getStack() - 1);
        emitShort((short) -1); // Must be patched later
        decStack();
    }

    public void opc_ifnonnull(short bciOffset) {
        emitByte(opc_ifnonnull);
        emitShort(bciOffset);
        decStack();
    }

    /** Control flow with forward-reference BCI. Stack assumes straight
        control flow. */
    public void opc_ifnonnull(Label l) {
        short instrBCI = getLength();
        emitByte(opc_ifnonnull);
        l.add(this, instrBCI, getLength(), getStack() - 1);
        emitShort((short) -1); // Must be patched later
        decStack();
    }

    /////////////////////////
    // Return instructions //
    /////////////////////////

    public void opc_ireturn() {
        emitByte(opc_ireturn);
        setStack(0);
    }

    public void opc_lreturn() {
        emitByte(opc_lreturn);
        setStack(0);
    }

    public void opc_freturn() {
        emitByte(opc_freturn);
        setStack(0);
    }

    public void opc_dreturn() {
        emitByte(opc_dreturn);
        setStack(0);
    }

    public void opc_areturn() {
        emitByte(opc_areturn);
        setStack(0);
    }

    public void opc_return() {
        emitByte(opc_return);
        setStack(0);
    }

    //////////////////////
    // Field operations //
    //////////////////////

    public void opc_getstatic(short fieldIndex, int fieldSizeInStackSlots) {
        emitByte(opc_getstatic);
        emitShort(fieldIndex);
        setStack(getStack() + fieldSizeInStackSlots);
    }

    public void opc_putstatic(short fieldIndex, int fieldSizeInStackSlots) {
        emitByte(opc_putstatic);
        emitShort(fieldIndex);
        setStack(getStack() - fieldSizeInStackSlots);
    }

    public void opc_getfield(short fieldIndex, int fieldSizeInStackSlots) {
        emitByte(opc_getfield);
        emitShort(fieldIndex);
        setStack(getStack() + fieldSizeInStackSlots - 1);
    }

    public void opc_putfield(short fieldIndex, int fieldSizeInStackSlots) {
        emitByte(opc_putfield);
        emitShort(fieldIndex);
        setStack(getStack() - fieldSizeInStackSlots - 1);
    }

    ////////////////////////
    // Method invocations //
    ////////////////////////

    /** Long and double arguments and return types count as 2 arguments;
        other values count as 1. */
    public void opc_invokevirtual(short methodIndex,
                                  int numArgs,
                                  int numReturnValues)
    {
        emitByte(opc_invokevirtual);
        emitShort(methodIndex);
        setStack(getStack() - numArgs - 1 + numReturnValues);
    }

    /** Long and double arguments and return types count as 2 arguments;
        other values count as 1. */
    public void opc_invokespecial(short methodIndex,
                                  int numArgs,
                                  int numReturnValues)
    {
        emitByte(opc_invokespecial);
        emitShort(methodIndex);
        setStack(getStack() - numArgs - 1 + numReturnValues);
    }

    /** Long and double arguments and return types count as 2 arguments;
        other values count as 1. */
    public void opc_invokestatic(short methodIndex,
                                 int numArgs,
                                 int numReturnValues)
    {
        emitByte(opc_invokestatic);
        emitShort(methodIndex);
        setStack(getStack() - numArgs + numReturnValues);
    }

    /** Long and double arguments and return types count as 2 arguments;
        other values count as 1. */
    public void opc_invokeinterface(short methodIndex,
                                    int numArgs,
                                    byte count,
                                    int numReturnValues)
    {
        emitByte(opc_invokeinterface);
        emitShort(methodIndex);
        emitByte(count);
        emitByte((byte) 0);
        setStack(getStack() - numArgs - 1 + numReturnValues);
    }

    //////////////////
    // Array length //
    //////////////////

    public void opc_arraylength() {
        emitByte(opc_arraylength);
    }

    /////////
    // New //
    /////////

    public void opc_new(short classIndex) {
        emitByte(opc_new);
        emitShort(classIndex);
        incStack();
    }

    ////////////
    // Athrow //
    ////////////

    public void opc_athrow() {
        emitByte(opc_athrow);
        setStack(1);
    }

    //////////////////////////////
    // Checkcast and instanceof //
    //////////////////////////////

    /** Assumes the checkcast succeeds */
    public void opc_checkcast(short classIndex) {
        emitByte(opc_checkcast);
        emitShort(classIndex);
    }

    public void opc_instanceof(short classIndex) {
        emitByte(opc_instanceof);
        emitShort(classIndex);
    }
}
