bytecodeparser.java

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

JAVA
1,117
字号
                    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 QUICK_GETSTATIC:
            case QUICK_GETSTATIC_WIDE:
            case 0xb2:
                {
                    VmConstFieldRef field = cp.getConstFieldRef(getu2());
                    handler.visit_getstatic(field);
                }
                break;
            case QUICK_PUTSTATIC:
            case QUICK_PUTSTATIC_WIDE:
            case 0xb3:
                {
                    VmConstFieldRef field = cp.getConstFieldRef(getu2());
                    handler.visit_putstatic(field);
                }
                break;
            // -- 180 --
            case QUICK_GETFIELD:
            case QUICK_GETFIELD_WIDE:
            case 0xb4:
                {
                    VmConstFieldRef field = cp.getConstFieldRef(getu2());
                    handler.visit_getfield(field);
                }
                break;
            case QUICK_PUTFIELD:
            case QUICK_PUTFIELD_WIDE:
            case 0xb5:
                {
                    VmConstFieldRef field = cp.getConstFieldRef(getu2());
                    handler.visit_putfield(field);
                }
                break;
            case QUICK_INVOKEVIRTUAL:
            case 0xb6:
                handler.visit_invokevirtual(cp.getConstMethodRef(getu2()));
                break;
            case QUICK_INVOKESPECIAL:
            case 0xb7:
                handler.visit_invokespecial(cp.getConstMethodRef(getu2()));
                break;
            case QUICK_INVOKESTATIC:
            case 0xb8:
                handler.visit_invokestatic(cp.getConstMethodRef(getu2()));
                break;
            case QUICK_INVOKEINTERFACE:
            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) {
                offset = continueAt;
            }
        }
        if (startEndMethod) {
            fireEndMethod();
        }
    }

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

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

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

    /**
     * Get a byte from the next bytecode position
     * 
     * @return byte
     */
    private final byte gets1() {
        return bytecode[ offset++];
    }

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

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

    private final void skipPadding() {
        while (offset % 4 != 0) {
            offset++;
        }
        paddedAddress = offset;
    }

    private final void skip() {
        offset++;
    }

    /**
     * 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 this.offset;
    }

    /**
     * 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(byte[] 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]);
            }
        }*/       
    }
}

⌨️ 快捷键说明

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