x86bytecodevisitor.java

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

JAVA
2,035
字号
        os.writeFSTP32(SP, 0);
    }

    /**
     * @param fieldRef
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_getfield(org.jnode.vm.classmgr.VmConstFieldRef)
     */
    public final void visit_getfield(VmConstFieldRef fieldRef) {
        fieldRef.resolve(loader);
        final VmField field = fieldRef.getResolvedVmField();
        if (field.isStatic()) { throw new IncompatibleClassChangeError(
                "getfield called on static field " + fieldRef.getName()); }
        final VmInstanceField inf = (VmInstanceField) field;
        final int offset = inf.getOffset();

        /** Objectref -> EBX */
        helper.writePOP(S0); // Objectref
        /* Get the data */
        if (!fieldRef.isWide()) {
            os.writeMOV(INTSIZE, T0, S0, offset);
            os.writePUSH(T0);
        } else {
            os.writeMOV(INTSIZE, T1, S0, offset + 4); // MSB
            os.writeMOV(INTSIZE, T0, S0, offset); // LSB
            helper.writePUSH64(T0, T1);
        }
    }

    /**
     * @param fieldRef
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_getstatic(org.jnode.vm.classmgr.VmConstFieldRef)
     */
    public final void visit_getstatic(VmConstFieldRef fieldRef) {
        fieldRef.resolve(loader);
        final VmStaticField sf = (VmStaticField) fieldRef.getResolvedVmField();
        if (!sf.getDeclaringClass().isInitialized()) {
            writeInitializeClass(fieldRef, S0);
        }
        // Get static field object
        if (!fieldRef.isWide()) {
            helper.writeGetStaticsEntry(curInstrLabel, T0, sf);
            helper.writePUSH(T0);
        } else {
            helper.writeGetStaticsEntry64(curInstrLabel, T0, T1, sf);
            helper.writePUSH64(T0, T1);
        }
    }

    /**
     * @param address
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_goto(int)
     */
    public final void visit_goto(int address) {
        os.writeJMP(helper.getInstrLabel(address));
    }

    /**
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_i2b()
     */
    public final void visit_i2b() {
        helper.writePOP(T0);
        os.writeMOVSX(T0, T0, BYTESIZE);
        helper.writePUSH(T0);
    }

    /**
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_i2c()
     */
    public final void visit_i2c() {
        helper.writePOP(T0);
        os.writeMOVZX(T0, T0, WORDSIZE);
        helper.writePUSH(T0);
    }

    /**
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_i2d()
     */
    public final void visit_i2d() {
        os.writeFILD32(SP, 0);
        os.writeLEA(SP, SP, -4);
        os.writeFSTP64(SP, 0);
    }

    /**
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_i2f()
     */
    public final void visit_i2f() {
        os.writeFILD32(SP, 0);
        os.writeFSTP32(SP, 0);
    }

    /**
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_i2l()
     */
    public final void visit_i2l() {
        helper.writePOP(Register.EAX);
        os.writeCDQ(); /* Sign extend EAX -> EDX:EAX */
        helper.writePUSH64(Register.EAX, Register.EDX);
    }

    /**
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_i2s()
     */
    public final void visit_i2s() {
        helper.writePOP(T0);
        os.writeMOVSX(T0, T0, WORDSIZE);
        helper.writePUSH(T0);
    }

    /**
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_iadd()
     */
    public final void visit_iadd() {
        helper.writePOP(T0); // value2
        helper.writePOP(S0); // value 1
        os.writeADD(S0, T0);
        helper.writePUSH(S0);
    }

    /**
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_iaload()
     */
    public final void visit_iaload() {
        helper.writePOP(S0); // Index
        helper.writePOP(T0); // Arrayref
        checkBounds(T0, S0);
        //os.writePUSH(T0, S0, 4, VmArray.DATA_OFFSET * 4);
        os.writeMOV(INTSIZE, T0, T0, S0, 4, VmArray.DATA_OFFSET * 4);
        helper.writePUSH(T0);
    }

    /**
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_iand()
     */
    public final void visit_iand() {
        helper.writePOP(T0); // value 2
        helper.writePOP(S0); // value 1
        os.writeAND(S0, T0);
        helper.writePUSH(S0);
    }

    /**
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_iastore()
     */
    public final void visit_iastore() {
        helper.writePOP(T1); // Value
        helper.writePOP(S0); // Index
        helper.writePOP(T0); // Arrayref
        checkBounds(T0, S0);
        os.writeMOV(INTSIZE, T0, S0, 4, VmArray.DATA_OFFSET * 4, T1);
    }

    /**
     * @param value
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_iconst(int)
     */
    public final void visit_iconst(int value) {
        helper.writePUSH(value);
    }

    /**
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_idiv()
     */
    public final void visit_idiv() {
        helper.writePOP(Register.ECX); // Value2
        helper.writePOP(Register.EAX); // Value1
        os.writeCDQ();
        os.writeIDIV_EAX(Register.ECX); // EAX = EDX:EAX / ECX
        helper.writePUSH(Register.EAX);
    }

    /**
     * Helper method for visit_if_icmpxx and visit_if_acmpxx
     * 
     * @param address
     * @param jccOpcode
     */
    private final void visit_if_xcmp(int address, int jccOpcode) {
        helper.writePOP(S0); // Value2
        helper.writePOP(T0); // Value1
        os.writeCMP(T0, S0);
        os.writeJCC(helper.getInstrLabel(address), jccOpcode);
    }

    /**
     * @param address
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_if_acmpeq(int)
     */
    public final void visit_if_acmpeq(int address) {
        visit_if_xcmp(address, X86Constants.JE); // JE
    }

    /**
     * @param address
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_if_acmpne(int)
     */
    public final void visit_if_acmpne(int address) {
        visit_if_xcmp(address, X86Constants.JNE); // JNE
    }

    /**
     * @param address
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_if_icmpeq(int)
     */
    public final void visit_if_icmpeq(int address) {
        visit_if_xcmp(address, X86Constants.JE); // JE
    }

    /**
     * @param address
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_if_icmpge(int)
     */
    public final void visit_if_icmpge(int address) {
        visit_if_xcmp(address, X86Constants.JGE); // JGE
    }

    /**
     * @param address
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_if_icmpgt(int)
     */
    public final void visit_if_icmpgt(int address) {
        visit_if_xcmp(address, X86Constants.JG); // JG
    }

    /**
     * @param address
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_if_icmple(int)
     */
    public final void visit_if_icmple(int address) {
        visit_if_xcmp(address, X86Constants.JLE); // JLE
    }

    /**
     * @param address
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_if_icmplt(int)
     */
    public final void visit_if_icmplt(int address) {
        visit_if_xcmp(address, X86Constants.JL); // JL
    }

    /**
     * @param address
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_if_icmpne(int)
     */
    public final void visit_if_icmpne(int address) {
        visit_if_xcmp(address, X86Constants.JNE); // JNE
    }

    private void visit_ifxx(int address, int jccOpcode) {
        helper.writePOP(EAX); // Value
        //os.writeCMP_EAX(0);
        os.writeTEST(EAX, EAX);
        os.writeJCC(helper.getInstrLabel(address), jccOpcode);
    }

    /**
     * @param address
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_ifeq(int)
     */
    public final void visit_ifeq(int address) {
        visit_ifxx(address, X86Constants.JE); // JE
    }

    /**
     * @param address
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_ifge(int)
     */
    public final void visit_ifge(int address) {
        visit_ifxx(address, X86Constants.JGE); // JGE
    }

    /**
     * @param address
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_ifgt(int)
     */
    public final void visit_ifgt(int address) {
        visit_ifxx(address, X86Constants.JG); // JG
    }

    /**
     * @param address
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_ifle(int)
     */
    public final void visit_ifle(int address) {
        visit_ifxx(address, X86Constants.JLE); // JLE
    }

    /**
     * @param address
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_iflt(int)
     */
    public final void visit_iflt(int address) {
        visit_ifxx(address, X86Constants.JL); // JL
    }

    /**
     * @param address
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_ifne(int)
     */
    public final void visit_ifne(int address) {
        visit_ifxx(address, X86Constants.JNE); // JNE
    }

    /**
     * @param address
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_ifnonnull(int)
     */
    public final void visit_ifnonnull(int address) {
        visit_ifxx(address, X86Constants.JNE);
    }

    /**
     * @param address
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_ifnull(int)
     */
    public final void visit_ifnull(int address) {
        visit_ifxx(address, X86Constants.JE);
    }

    /**
     * @param index
     * @param incValue
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_iinc(int, int)
     */
    public final void visit_iinc(int index, int incValue) {
        final int ebpOfs = stackFrame.getEbpOffset(index);
        os.writeMOV_Const(T0, incValue);
        os.writeADD(FP, ebpOfs, T0);
    }

    /**
     * @param index
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_iload(int)
     */
    public final void visit_iload(int index) {
        final int ebpOfs = stackFrame.getEbpOffset(index);
        os.writeMOV(INTSIZE, T0, FP, ebpOfs);
        helper.writePUSH(T0);
    }

    /**
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_imul()
     */
    public final void visit_imul() {
        helper.writePOP(S0); // Value2
        helper.writePOP(EAX); // Value1
        os.writeIMUL_EAX(S0); // EDX:EAX = EAX*S0
        helper.writePUSH(EAX);
    }

    /**
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_ineg()
     */
    public final void visit_ineg() {
        helper.writePOP(T0);
        os.writeNEG(T0);
        helper.writePUSH(T0);
    }

    /**
     * @param classRef
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_instanceof(org.jnode.vm.classmgr.VmConstClass)
     */
    public final void visit_instanceof(VmConstClass classRef) {
        /* Objectref is already on the stack */
        writeResolveAndLoadClassToEAX(classRef, S0);

        final Label trueLabel = new Label(this.curInstrLabel + "io-true");
        final Label endLabel = new Label(this.curInstrLabel + "io-end");

        /* Pop objectref */
        helper.writePOP(Register.ECX);
        /* Is instanceof? */
        instanceOf(trueLabel);
        /* Not instanceof */
        os.writeXOR(T0, T0);
        os.writeJMP(endLabel);

        os.setObjectRef(trueLabel);
        os.writeMOV_Const(T0, 1);

        os.setObjectRef(endLabel);
        os.writePUSH(T0);
    }

    /**
     * @param methodRef
     * @param count
     * @see org.jnode.vm.bytecode.BytecodeVisitor#visit_invokeinterface(VmConstIMethodRef,
     *      int)
     */
    public final void visit_invokeinterface(VmConstIMethodRef methodRef,
            int count) {
        methodRef.resolve(loader);
        /*
         * if (!methodRef.getConstClass().isResolved()) { Label startClassLabel =
         * new Label(this.curInstrLabel + "startClass");
         * os.setObjectRef(startClassLabel);
         * resolveClass(methodRef.getConstClass()); patch_NOP(startClassLabel); }
         * 
         * if (!methodRef.isResolved()) { Label startLabel = new
         * Label(this.curInstrLabel + "start"); os.setObjectRef(startLabel);
         * resolveMethod(methodRef); patch_NOP(startLabel);
         */

        final VmMethod method = methodRef.getResolvedVmMethod();
        final int selector = method.getSelector();

⌨️ 快捷键说明

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