bytecodeparser.java

来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 1,117 行 · 第 1/3 页

JAVA
1,117
字号
/**
 * $Id: BytecodeParser.java,v 1.8 2004/02/24 08:04:23 epr Exp $
 * 
 * Copyright 2001-2003, E.W. Prangsma
 * 
 * All rights reserved
 */
package org.jnode.vm.bytecode;

import org.jnode.vm.classmgr.VmByteCode;
import org.jnode.vm.classmgr.VmCP;
import org.jnode.vm.classmgr.VmConstClass;
import org.jnode.vm.classmgr.VmConstFieldRef;
import org.jnode.vm.classmgr.VmConstIMethodRef;
import org.jnode.vm.classmgr.VmConstString;
import org.jnode.vm.classmgr.VmMethod;

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

    /*
     * The following value must not be changed. The native code of interpreter
     * jumptables depend on them.
     */
    public static final int QUICK_GETSTATIC = 210;

    public static final int QUICK_PUTSTATIC = 211;

    public static final int QUICK_GETFIELD = 212;

    public static final int QUICK_PUTFIELD = 213;

    public static final int QUICK_GETSTATIC_WIDE = 214;

    public static final int QUICK_PUTSTATIC_WIDE = 215;

    public static final int QUICK_GETFIELD_WIDE = 216;

    public static final int QUICK_PUTFIELD_WIDE = 217;

    public static final int QUICK_INVOKEVIRTUAL = 218;

    public static final int QUICK_INVOKESPECIAL = 219;

    public static final int QUICK_INVOKESTATIC = 220;

    public static final int QUICK_INVOKEINTERFACE = 221;

    private final VmByteCode bc;

    private final VmCP cp;

    private byte[] bytecode;

    private final BytecodeVisitor handler;

    private int offset;

    private int address;

    private boolean wide;

    private int opcode;

    private int paddedAddress;

    private int continueAt;

    private int endPC;

    //private static int[] counters = new int[ 256];

    /**
     * @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.length, 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;
        offset = startPC;
        this.endPC = endPCArg;
        handler.setParser(this);
        if (startEndMethod) {
            fireStartMethod(bc.getMethod());
        }

        while (offset < endPC) {

            // The address(offset) of the current instruction
            this.continueAt = -1;
            this.address = offset;
            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:
                {
                    cpIdx = getu1();
                    final Object o = cp.getAny(cpIdx);
                    if (o instanceof Integer) {
                        handler.visit_iconst(((Integer) o).intValue());
                    } else if (o instanceof Float) {
                        handler.visit_fconst(((Float) o).floatValue());
                    } else {
                        handler.visit_ldc((VmConstString) o);
                    }
                }
                break;
            case 0x13:
                {
                    cpIdx = getu2();
                    final Object o = cp.getAny(cpIdx);
                    if (o instanceof Integer) {
                        handler.visit_iconst(((Integer) o).intValue());
                    } else if (o instanceof Float) {
                        handler.visit_fconst(((Float) o).floatValue());
                    } else {
                        handler.visit_ldc((VmConstString) o);
                    }
                }
                break;
            // -- 20 --
            case 0x14:
                {
                    final Object o = cp.getAny(getu2());
                    if (o instanceof Long) {
                        handler.visit_lconst(((Long) o).longValue());
                    } else {
                        handler.visit_dconst(((Double) o).doubleValue());
                    }
                }
                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:

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?