Package org.jnode.vm.bytecode

Source Code of org.jnode.vm.bytecode.BytecodeParser

/*
* $Id$
*
* Copyright (C) 2003-2014 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library 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 Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.vm.bytecode;

import java.nio.ByteBuffer;
import org.jnode.vm.classmgr.VmByteCode;
import org.jnode.vm.classmgr.VmCP;
import org.jnode.vm.classmgr.VmConstClass;
import org.jnode.vm.classmgr.VmConstDouble;
import org.jnode.vm.classmgr.VmConstFieldRef;
import org.jnode.vm.classmgr.VmConstFloat;
import org.jnode.vm.classmgr.VmConstIMethodRef;
import org.jnode.vm.classmgr.VmConstInt;
import org.jnode.vm.classmgr.VmConstLong;
import org.jnode.vm.classmgr.VmConstObject;
import org.jnode.vm.classmgr.VmConstString;
import org.jnode.vm.classmgr.VmMethod;

/**
* <description>
*
* @author epr
*/
public class BytecodeParser {

    private final VmByteCode bc;

    private final VmCP cp;

    private ByteBuffer bytecode;

    private final BytecodeVisitor handler;

    private int address;

    private boolean wide;

    private int opcode;

    private int paddedAddress;

    private int continueAt;

    private int endPC;

    /**
     * @return The padded address
     */
    public final int getPaddedAddress() {
        return this.paddedAddress;
    }

    /**
     * Create a new instance
     *
     * @param bc
     * @param handler
     */
    protected BytecodeParser(VmByteCode bc, BytecodeVisitor handler) {
        this.bc = bc;
        this.bytecode = bc.getBytecode();
        this.cp = bc.getCP();
        this.handler = handler;
    }

    /**
     * Parse a given bytecode
     *
     * @param bc
     * @param handler
     * @throws ClassFormatError
     */
    public static void parse(VmByteCode bc, BytecodeVisitor handler)
        throws ClassFormatError {
        new BytecodeParser(bc, handler).parse();
    }

    /**
     * Parse a given bytecode
     *
     * @param bc
     * @param handler
     * @param startPC        The program counter where to start parsing (inclusive)
     * @param endPC          The program counter where to stop parsing (exclusive)
     * @param startEndMethod Should startMethod and endMethod be called.
     * @throws ClassFormatError
     */
    public static void parse(VmByteCode bc, BytecodeVisitor handler,
                             int startPC, int endPC, boolean startEndMethod)
        throws ClassFormatError {
        new BytecodeParser(bc, handler).parse(startPC, endPC, startEndMethod);
    }

    /**
     * Parse a given bytecode
     *
     * @throws ClassFormatError
     */
    public void parse() throws ClassFormatError {
        parse(0, bytecode.limit(), true);
    }

    /**
     * Parse a selected region of the bytecode
     *
     * @param startPC  The program counter where to start parsing (inclusive)
     * @param endPCArg The program counter where to stop parsing (exclusive)
     * @throws ClassFormatError
     */
    public void parse(int startPC, int endPCArg, boolean startEndMethod)
        throws ClassFormatError {

        final BytecodeVisitor handler = this.handler;
        bytecode.position(startPC);
        this.endPC = endPCArg;
        handler.setParser(this);
        if (startEndMethod) {
            fireStartMethod(bc.getMethod());
        }

        while (bytecode.position() < endPC) {

            // The address(offset) of the current instruction
            this.continueAt = -1;
            this.address = bytecode.position();
            this.wide = false;
            fireStartInstruction(address);
            this.opcode = getu1();
            final int cpIdx;

            //counters[ opcode]++;
            switch (opcode) {
                // -- 0 --
                case 0x00:
                    handler.visit_nop();
                    break;
                case 0x01:
                    handler.visit_aconst_null();
                    break;
                case 0x02:
                    handler.visit_iconst(-1);
                    break;
                case 0x03:
                    handler.visit_iconst(0);
                    break;
                case 0x04:
                    handler.visit_iconst(1);
                    break;
                case 0x05:
                    handler.visit_iconst(2);
                    break;
                case 0x06:
                    handler.visit_iconst(3);
                    break;
                case 0x07:
                    handler.visit_iconst(4);
                    break;
                case 0x08:
                    handler.visit_iconst(5);
                    break;
                case 0x09:
                    handler.visit_lconst(0L);
                    break;
                    // -- 10 --
                case 0x0a:
                    handler.visit_lconst(1l);
                    break;
                case 0x0b:
                    handler.visit_fconst(0.0f);
                    break;
                case 0x0c:
                    handler.visit_fconst(1.0f);
                    break;
                case 0x0d:
                    handler.visit_fconst(2.0f);
                    break;
                case 0x0e:
                    handler.visit_dconst(0.0);
                    break;
                case 0x0f:
                    handler.visit_dconst(1.0);
                    break;
                case 0x10:
                    handler.visit_iconst(gets1()); // bipush
                    break;
                case 0x11:
                    handler.visit_iconst(gets2()); // sipush
                    break;
                case 0x12:
                case 0x13: {
                    if (opcode == 0x12) {
                        cpIdx = getu1();
                    } else {
                        cpIdx = getu2();
                    }
                    final VmConstObject o = (VmConstObject) cp.getAny(cpIdx);
                    switch (o.getConstType()) {
                        case VmConstObject.CONST_INT:
                            handler.visit_iconst(((VmConstInt) o).intValue());
                            break;
                        case VmConstObject.CONST_FLOAT:
                            handler.visit_fconst(((VmConstFloat) o).floatValue());
                            break;
                        case VmConstObject.CONST_CLASS:
                            handler.visit_ldc((VmConstClass) o);
                            break;
                        case VmConstObject.CONST_STRING:
                            handler.visit_ldc((VmConstString) o);
                            break;
                        default:
                            throw new ClassFormatError("Unknown constant pool type: " + o.getConstType());
                    }
                    break;
                }
                // -- 20 --
                case 0x14: {
                    final VmConstObject o = (VmConstObject) cp.getAny(getu2());
                    switch (o.getConstType()) {
                        case VmConstObject.CONST_LONG:
                            handler.visit_lconst(((VmConstLong) o).longValue());
                            break;
                        case VmConstObject.CONST_DOUBLE:
                            handler.visit_dconst(((VmConstDouble) o).doubleValue());
                            break;
                        default:
                            throw new ClassFormatError("Unknown constant pool type: " + o.getConstType());
                    }
                    break;
                }
                case 0x15:
                    handler.visit_iload(getu1());
                    break;
                case 0x16:
                    handler.visit_lload(getu1());
                    break;
                case 0x17:
                    handler.visit_fload(getu1());
                    break;
                case 0x18:
                    handler.visit_dload(getu1());
                    break;
                case 0x19:
                    handler.visit_aload(getu1());
                    break;
                case 0x1a:
                    handler.visit_iload(0);
                    break;
                case 0x1b:
                    handler.visit_iload(1);
                    break;
                case 0x1c:
                    handler.visit_iload(2);
                    break;
                case 0x1d:
                    handler.visit_iload(3);
                    break;
                    // -- 30 --
                case 0x1e:
                    handler.visit_lload(0);
                    break;
                case 0x1f:
                    handler.visit_lload(1);
                    break;
                case 0x20:
                    handler.visit_lload(2);
                    break;
                case 0x21:
                    handler.visit_lload(3);
                    break;
                case 0x22:
                    handler.visit_fload(0);
                    break;
                case 0x23:
                    handler.visit_fload(1);
                    break;
                case 0x24:
                    handler.visit_fload(2);
                    break;
                case 0x25:
                    handler.visit_fload(3);
                    break;
                case 0x26:
                    handler.visit_dload(0);
                    break;
                case 0x27:
                    handler.visit_dload(1);
                    break;
                    // -- 40 --
                case 0x28:
                    handler.visit_dload(2);
                    break;
                case 0x29:
                    handler.visit_dload(3);
                    break;
                case 0x2a:
                    handler.visit_aload(0);
                    break;
                case 0x2b:
                    handler.visit_aload(1);
                    break;
                case 0x2c:
                    handler.visit_aload(2);
                    break;
                case 0x2d:
                    handler.visit_aload(3);
                    break;
                case 0x2e:
                    handler.visit_iaload();
                    break;
                case 0x2f:
                    handler.visit_laload();
                    break;
                case 0x30:
                    handler.visit_faload();
                    break;
                case 0x31:
                    handler.visit_daload();
                    break;
                    // -- 50 --
                case 0x32:
                    handler.visit_aaload();
                    break;
                case 0x33:
                    handler.visit_baload();
                    break;
                case 0x34:
                    handler.visit_caload();
                    break;
                case 0x35:
                    handler.visit_saload();
                    break;
                case 0x36:
                    handler.visit_istore(getu1());
                    break;
                case 0x37:
                    handler.visit_lstore(getu1());
                    break;
                case 0x38:
                    handler.visit_fstore(getu1());
                    break;
                case 0x39:
                    handler.visit_dstore(getu1());
                    break;
                case 0x3a:
                    handler.visit_astore(getu1());
                    break;
                case 0x3b:
                    handler.visit_istore(0);
                    break;
                    // -- 60 --
                case 0x3c:
                    handler.visit_istore(1);
                    break;
                case 0x3d:
                    handler.visit_istore(2);
                    break;
                case 0x3e:
                    handler.visit_istore(3);
                    break;
                case 0x3f:
                    handler.visit_lstore(0);
                    break;
                case 0x40:
                    handler.visit_lstore(1);
                    break;
                case 0x41:
                    handler.visit_lstore(2);
                    break;
                case 0x42:
                    handler.visit_lstore(3);
                    break;
                case 0x43:
                    handler.visit_fstore(0);
                    break;
                case 0x44:
                    handler.visit_fstore(1);
                    break;
                case 0x45:
                    handler.visit_fstore(2);
                    break;
                    // -- 70 --
                case 0x46:
                    handler.visit_fstore(3);
                    break;
                case 0x47:
                    handler.visit_dstore(0);
                    break;
                case 0x48:
                    handler.visit_dstore(1);
                    break;
                case 0x49:
                    handler.visit_dstore(2);
                    break;
                case 0x4a:
                    handler.visit_dstore(3);
                    break;
                case 0x4b:
                    handler.visit_astore(0);
                    break;
                case 0x4c:
                    handler.visit_astore(1);
                    break;
                case 0x4d:
                    handler.visit_astore(2);
                    break;
                case 0x4e:
                    handler.visit_astore(3);
                    break;
                case 0x4f:
                    handler.visit_iastore();
                    break;
                    // -- 80 --
                case 0x50:
                    handler.visit_lastore();
                    break;
                case 0x51:
                    handler.visit_fastore();
                    break;
                case 0x52:
                    handler.visit_dastore();
                    break;
                case 0x53:
                    handler.visit_aastore();
                    break;
                case 0x54:
                    handler.visit_bastore();
                    break;
                case 0x55:
                    handler.visit_castore();
                    break;
                case 0x56:
                    handler.visit_sastore();
                    break;
                case 0x57:
                    handler.visit_pop();
                    break;
                case 0x58:
                    handler.visit_pop2();
                    break;
                case 0x59:
                    handler.visit_dup();
                    break;
                    // -- 90 --
                case 0x5a:
                    handler.visit_dup_x1();
                    break;
                case 0x5b:
                    handler.visit_dup_x2();
                    break;
                case 0x5c:
                    handler.visit_dup2();
                    break;
                case 0x5d:
                    handler.visit_dup2_x1();
                    break;
                case 0x5e:
                    handler.visit_dup2_x2();
                    break;
                case 0x5f:
                    handler.visit_swap();
                    break;
                case 0x60:
                    handler.visit_iadd();
                    break;
                case 0x61:
                    handler.visit_ladd();
                    break;
                case 0x62:
                    handler.visit_fadd();
                    break;
                case 0x63:
                    handler.visit_dadd();
                    break;
                    // -- 100 --
                case 0x64:
                    handler.visit_isub();
                    break;
                case 0x65:
                    handler.visit_lsub();
                    break;
                case 0x66:
                    handler.visit_fsub();
                    break;
                case 0x67:
                    handler.visit_dsub();
                    break;
                case 0x68:
                    handler.visit_imul();
                    break;
                case 0x69:
                    handler.visit_lmul();
                    break;
                case 0x6a:
                    handler.visit_fmul();
                    break;
                case 0x6b:
                    handler.visit_dmul();
                    break;
                case 0x6c:
                    handler.visit_idiv();
                    break;
                case 0x6d:
                    handler.visit_ldiv();
                    break;
                    // -- 110 --
                case 0x6e:
                    handler.visit_fdiv();
                    break;
                case 0x6f:
                    handler.visit_ddiv();
                    break;
                case 0x70:
                    handler.visit_irem();
                    break;
                case 0x71:
                    handler.visit_lrem();
                    break;
                case 0x72:
                    handler.visit_frem();
                    break;
                case 0x73:
                    handler.visit_drem();
                    break;
                case 0x74:
                    handler.visit_ineg();
                    break;
                case 0x75:
                    handler.visit_lneg();
                    break;
                case 0x76:
                    handler.visit_fneg();
                    break;
                case 0x77:
                    handler.visit_dneg();
                    break;
                    // -- 120 --
                case 0x78:
                    handler.visit_ishl();
                    break;
                case 0x79:
                    handler.visit_lshl();
                    break;
                case 0x7a:
                    handler.visit_ishr();
                    break;
                case 0x7b:
                    handler.visit_lshr();
                    break;
                case 0x7c:
                    handler.visit_iushr();
                    break;
                case 0x7d:
                    handler.visit_lushr();
                    break;
                case 0x7e:
                    handler.visit_iand();
                    break;
                case 0x7f:
                    handler.visit_land();
                    break;
                case 0x80:
                    handler.visit_ior();
                    break;
                case 0x81:
                    handler.visit_lor();
                    break;
                    // -- 130 --
                case 0x82:
                    handler.visit_ixor();
                    break;
                case 0x83:
                    handler.visit_lxor();
                    break;
                case 0x84: {
                    int idx = getu1();
                    handler.visit_iinc(idx, gets1());
                    break;
                }
                case 0x85:
                    handler.visit_i2l();
                    break;
                case 0x86:
                    handler.visit_i2f();
                    break;
                case 0x87:
                    handler.visit_i2d();
                    break;
                case 0x88:
                    handler.visit_l2i();
                    break;
                case 0x89:
                    handler.visit_l2f();
                    break;
                case 0x8a:
                    handler.visit_l2d();
                    break;
                case 0x8b:
                    handler.visit_f2i();
                    break;
                    // -- 140 --
                case 0x8c:
                    handler.visit_f2l();
                    break;
                case 0x8d:
                    handler.visit_f2d();
                    break;
                case 0x8e:
                    handler.visit_d2i();
                    break;
                case 0x8f:
                    handler.visit_d2l();
                    break;
                case 0x90:
                    handler.visit_d2f();
                    break;
                case 0x91:
                    handler.visit_i2b();
                    break;
                case 0x92:
                    handler.visit_i2c();
                    break;
                case 0x93:
                    handler.visit_i2s();
                    break;
                case 0x94:
                    handler.visit_lcmp();
                    break;
                case 0x95:
                    handler.visit_fcmpl();
                    break;
                    // -- 150 --
                case 0x96:
                    handler.visit_fcmpg();
                    break;
                case 0x97:
                    handler.visit_dcmpl();
                    break;
                case 0x98:
                    handler.visit_dcmpg();
                    break;
                case 0x99:
                    handler.visit_ifeq(address + gets2());
                    break;
                case 0x9a:
                    handler.visit_ifne(address + gets2());
                    break;
                case 0x9b:
                    handler.visit_iflt(address + gets2());
                    break;
                case 0x9c:
                    handler.visit_ifge(address + gets2());
                    break;
                case 0x9d:
                    handler.visit_ifgt(address + gets2());
                    break;
                case 0x9e:
                    handler.visit_ifle(address + gets2());
                    break;
                case 0x9f:
                    handler.visit_if_icmpeq(address + gets2());
                    break;
                    // -- 160 --
                case 0xa0:
                    handler.visit_if_icmpne(address + gets2());
                    break;
                case 0xa1:
                    handler.visit_if_icmplt(address + gets2());
                    break;
                case 0xa2:
                    handler.visit_if_icmpge(address + gets2());
                    break;
                case 0xa3:
                    handler.visit_if_icmpgt(address + gets2());
                    break;
                case 0xa4:
                    handler.visit_if_icmple(address + gets2());
                    break;
                case 0xa5:
                    handler.visit_if_acmpeq(address + gets2());
                    break;
                case 0xa6:
                    handler.visit_if_acmpne(address + gets2());
                    break;
                case 0xa7:
                    handler.visit_goto(address + gets2());
                    break;
                case 0xa8:
                    handler.visit_jsr(address + gets2());
                    break;
                case 0xa9:
                    handler.visit_ret(getu1());
                    break;
                    // -- 170 --
                case 0xaa: {
                    skipPadding();
                    int defAddress = address + gets4();
                    int lowValue = gets4();
                    int highValue = gets4();
                    if (highValue < lowValue) {
                        throw new ClassFormatError(
                            "tableSwitch high < low! (high=" + highValue
                                + ", low=" + lowValue + ')');
                    }
                    int cnt = highValue - lowValue + 1;
                    int addresses[] = new int[cnt];
                    for (int i = 0; i < cnt; i++) {
                        addresses[i] = address + gets4();
                    }
                    handler.visit_tableswitch(defAddress, lowValue, highValue, addresses);
                    break;
                }
                case 0xab: {
                    skipPadding();
                    int defAddress = address + gets4();
                    int cnt = getu4();
                    int matches[] = new int[cnt];
                    int addresses[] = new int[cnt];
                    for (int i = 0; i < cnt; i++) {
                        matches[i] = gets4();
                        addresses[i] = address + gets4();
                    }
                    handler.visit_lookupswitch(defAddress, matches, addresses);
                    break;
                }
                case 0xac:
                    handler.visit_ireturn();
                    break;
                case 0xad:
                    handler.visit_lreturn();
                    break;
                case 0xae:
                    handler.visit_freturn();
                    break;
                case 0xaf:
                    handler.visit_dreturn();
                    break;
                case 0xb0:
                    handler.visit_areturn();
                    break;
                case 0xb1:
                    handler.visit_return();
                    break;
                case 0xb2: {
                    VmConstFieldRef field = cp.getConstFieldRef(getu2());
                    handler.visit_getstatic(field);
                    break;
                }
                case 0xb3: {
                    VmConstFieldRef field = cp.getConstFieldRef(getu2());
                    handler.visit_putstatic(field);
                    break;
                }
                // -- 180 --
                case 0xb4: {
                    VmConstFieldRef field = cp.getConstFieldRef(getu2());
                    handler.visit_getfield(field);
                    break;
                }
                case 0xb5: {
                    VmConstFieldRef field = cp.getConstFieldRef(getu2());
                    handler.visit_putfield(field);
                    break;
                }
                case 0xb6:
                    handler.visit_invokevirtual(cp.getConstMethodRef(getu2()));
                    break;
                case 0xb7:
                    handler.visit_invokespecial(cp.getConstMethodRef(getu2()));
                    break;
                case 0xb8:
                    handler.visit_invokestatic(cp.getConstMethodRef(getu2()));
                    break;
                case 0xb9: {
                    VmConstIMethodRef ref = cp.getConstIMethodRef(getu2());
                    int count = getu1();
                    skip();
                    handler.visit_invokeinterface(ref, count);
                    break;
                }
                //case 0xba: handler.throw_invalid_opcode ; unused
                case 0xbb:
                    handler.visit_new(cp.getConstClass(getu2()));
                    break;
                case 0xbc:
                    handler.visit_newarray(getu1());
                    break;
                case 0xbd:
                    handler.visit_anewarray(cp.getConstClass(getu2()));
                    break;
                    // -- 190 --
                case 0xbe:
                    handler.visit_arraylength();
                    break;
                case 0xbf:
                    handler.visit_athrow();
                    break;
                case 0xc0:
                    handler.visit_checkcast(cp.getConstClass(getu2()));
                    break;
                case 0xc1:
                    handler.visit_instanceof(cp.getConstClass(getu2()));
                    break;
                case 0xc2:
                    handler.visit_monitorenter();
                    break;
                case 0xc3:
                    handler.visit_monitorexit();
                    break;
                case 0xc4: {
                    wide = true;
                    int opcode = getu1();
                    if (opcode == 0x84) {
                        int idx = getu2();
                        int constValue = gets2();
                        handler.visit_iinc(idx, constValue);
                    } else {
                        int idx = getu2();
                        switch (opcode) {
                            case 0x15:
                                handler.visit_iload(idx);
                                break;
                            case 0x16:
                                handler.visit_lload(idx);
                                break;
                            case 0x17:
                                handler.visit_fload(idx);
                                break;
                            case 0x18:
                                handler.visit_dload(idx);
                                break;
                            case 0x19:
                                handler.visit_aload(idx);
                                break;
                            case 0x36:
                                handler.visit_istore(idx);
                                break;
                            case 0x37:
                                handler.visit_lstore(idx);
                                break;
                            case 0x38:
                                handler.visit_fstore(idx);
                                break;
                            case 0x39:
                                handler.visit_dstore(idx);
                                break;
                            case 0x3a:
                                handler.visit_astore(idx);
                                break;
                            default:
                                throw new ClassFormatError(
                                    "Invalid opcode in wide instruction");
                        }
                    }
                    break;
                }
                case 0xc5: {
                    VmConstClass clazz = cp.getConstClass(getu2());
                    int dims = getu1();
                    handler.visit_multianewarray(clazz, dims);
                    break;
                }
                case 0xc6:
                    handler.visit_ifnull(address + gets2());
                    break;
                case 0xc7:
                    handler.visit_ifnonnull(address + gets2());
                    break;
                    // -- 200 --
                case 0xc8:
                    handler.visit_goto(address + gets4());
                    break;
                case 0xc9:
                    handler.visit_jsr(address + gets4());
                    break;
                default:
                    throw new ClassFormatError("Invalid opcode");
            }
            fireEndInstruction();
            if (continueAt >= 0) {
                bytecode.position(continueAt);
            }
        }
        if (startEndMethod) {
            fireEndMethod();
        }
    }

    /**
     * Get an unsigned byte from the next bytecode position
     *
     * @return int
     */
    private final int getu1() {
        return bytecode.get() & 0xFF;
    }

    /**
     * Get an unsigned short from the next bytecode position
     *
     * @return int
     */
    private final int getu2() {
        int v1 = bytecode.get() & 0xFF;
        int v2 = bytecode.get() & 0xFF;
        return (v1 << 8) | v2;
    }

    /**
     * Get an unsigned int from the next bytecode position
     *
     * @return int
     */
    private final int getu4() {
        int v1 = bytecode.get() & 0xFF;
        int v2 = bytecode.get() & 0xFF;
        int v3 = bytecode.get() & 0xFF;
        int v4 = bytecode.get() & 0xFF;
        return (v1 << 24) | (v2 << 16) | (v3 << 8) | v4;
    }

    /**
     * Get a byte from the next bytecode position
     *
     * @return byte
     */
    private final byte gets1() {
        return bytecode.get();
    }

    /**
     * Get a short from the next bytecode positions
     *
     * @return short
     */
    private final short gets2() {
        int v1 = bytecode.get() & 0xFF;
        int v2 = bytecode.get() & 0xFF;
        return (short) ((v1 << 8) | v2);
    }

    /**
     * Get an int from the next bytecode position
     *
     * @return int
     */
    private final int gets4() {
        int v1 = bytecode.get() & 0xFF;
        int v2 = bytecode.get() & 0xFF;
        int v3 = bytecode.get() & 0xFF;
        int v4 = bytecode.get() & 0xFF;
        return (v1 << 24) | (v2 << 16) | (v3 << 8) | v4;
    }

    private final void skipPadding() {
        while (bytecode.position() % 4 != 0) {
            bytecode.get();
        }
        paddedAddress = bytecode.position();
    }

    private final void skip() {
        bytecode.get();
    }

    /**
     * Gets the address of the current instruction in the parse method.
     *
     * @return int
     */
    public final int getAddress() {
        return this.address;
    }

    /**
     * Gets the address of the next instruction in the parse method.
     *
     * @return int
     */
    public final int getNextAddress() {
        return bytecode.position();
    }

    /**
     * Is the current instruction a wide instruction
     *
     * @return boolean
     */
    public final boolean isWide() {
        return this.wide;
    }

    /**
     * Gets the opcode of the current instruction
     *
     * @return int
     */
    public final int getOpcode() {
        return this.opcode;
    }

    public final void setContinueAt(int offset) {
        continueAt = offset;
    }

    public final void setCode(ByteBuffer bytecode) {
        this.bytecode = bytecode;
    }

    public final void adjustEndPC(int delta) {
        endPC += delta;
    }

    public final void setEndPC(int offset) {
        endPC = offset;
    }

    /**
     * @return The end PC of the parsable block
     */
    public int getEndPC() {
        return this.endPC;
    }

    /**
     * Call the startInstruction method of the handler.
     *
     * @param address
     */
    protected void fireStartInstruction(int address) {
        handler.startInstruction(address);
    }

    /**
     * Call the endInstruction method of the handler.
     */
    protected void fireEndInstruction() {
        handler.endInstruction();
    }

    /**
     * Call the startInstruction method of the handler.
     *
     * @param method
     */
    protected void fireStartMethod(VmMethod method) {
        handler.startMethod(method);
    }

    /**
     * Call the endMethod method of the handler.
     */
    protected void fireEndMethod() {
        handler.endMethod();
    }

    public static void dumpStatistics() {
        /*for (int i = 0; i < 256; i++) {
            if (counters[ i] != 0) {
                System.out.println("0x" + Integer.toHexString(i) + "\t" + counters[ i]);
            }
        }*/
    }
}
TOP

Related Classes of org.jnode.vm.bytecode.BytecodeParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.