一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

用Java實(shí)現(xiàn)JVM第五章《指令集和解釋器》

 小傅哥 2021-12-13

案例介紹
本案例通過(guò)java代碼實(shí)現(xiàn)jvm規(guī)范中指令集和解釋器,完成后就可以開始執(zhí)行1到100的加和計(jì)算。

Java虛擬機(jī)顧名思義,就是一臺(tái)虛擬的機(jī)器,而字節(jié)碼(bytecode)就是運(yùn)行在這臺(tái)虛擬機(jī)器上的機(jī)器碼。我們已經(jīng)知道,每一個(gè)類或者接口都會(huì)被Java編譯器編譯成一個(gè)class文件,類或接口的方法信息就放在class文件的method_info結(jié)構(gòu)中。如果方法不是抽象的,也不是本地方法,方法的Java代碼就會(huì)被編譯器編譯成字節(jié)碼(即使方法是空的,編譯器也會(huì)生成一條return語(yǔ)句),存在method_info結(jié)構(gòu)的Code屬性中。

環(huán)境準(zhǔn)備
1、jdk 1.8.0
2、IntelliJ IDEA Community Edition 2018.3.1 x64

配置信息
1、調(diào)試配置
2.1、配置位置:Run/Debug Configurations -> program arguments
2.2、配置內(nèi)容:-Xjre “C:\Program Files\Java\jdk1.8.0_161\jre” E:\itstack\git\istack-demo\itstack-demo-jvm\itstack-demo-jvm-05\target\test-classes\org\itstack\demo\test\HelloWorld

代碼示例

itstack-demo-jvm-05
├── pom.xml
└── src
    └── main
    │    └── java
    │        └── org.itstack.demo.jvm
│             ├── classfile
    │             │   ├── attributes   {BootstrapMethods/Code/ConstantValue...}
    │             │   ├── constantpool {CONSTANT_TAG_CLASS/CONSTANT_TAG_FIELDREF/CONSTANT_TAG_METHODREF...}
    │             │   ├── ClassFile.java
    │             │   ├── ClassReader.java
    │             │   └── MemberInfo.java
    │             ├── classpath
    │             │   ├── impl
    │             │   │   ├── CompositeEntry.java
    │             │   │   ├── DirEntry.java 
    │             │   │   ├── WildcardEntry.java 
    │             │   │   └── ZipEntry.java    
    │             │   ├── Classpath.java
    │             │   └── Entry.java   
    │             ├── classpath
    │             │   ├── base
    │             │   ├── comparisons
    │             │   ├── constants
    │             │   ├── control
    │             │   ├── conversions
    │             │   ├── extended
    │             │   ├── loads
    │             │   ├── math
    │             │   │   ├── add
    │             │   │   ├── and
    │             │   │   ├── div
    │             │   │   ├── iinc
    │             │   │   ├── mul
    │             │   │   ├── neg
    │             │   │   ├── or
    │             │   │   ├── rem
    │             │   │   ├── sh
    │             │   │   ├── sub
    │             │   │   └── xor
    │             │   ├── stack
    │             │   ├── store
    │             │   └── Factory
    │             ├── rtda
    │             │   ├── Frame.java
    │             │   ├── JvmStack.java
    │             │   ├── LocalVars.java
    │             │   ├── OperandStack.java
    │             │   ├── Slot.java
    │             │   └── Thread.java
    │             ├── Cmd.java
    │             ├── Interpret.java
    │             └── Main.java
    └── test
         └── java
             └── org.itstack.demo.test
                 └── HelloWorld.java

Factory.java

public class Factory {

    public static Instruction newInstruction(byte opcode) {
        switch (opcode) {
            case 0x00:
                return new NOP();
            case 0x01:
                return new ACONST_NULL();
            case 0x02:
                return new ICONST_M1();
            case 0x03:
                return new ICONST_0();
            case 0x04:
                return new ICONST_1();
            case 0x05:
                return new ICONST_2();
            case 0x06:
                return new ICONST_3();
            case 0x07:
                return new ICONST_4();
            case 0x08:
                return new ICONST_5();
            case 0x09:
                return new LCONST_0();
            case 0x0a:
                return new LCONST_1();
            case 0x0b:
                return new FCONST_0();
            case 0x0c:
                return new FCONST_1();
            case 0x0d:
                return new FCONST_2();
            case 0x0e:
                return new DCONST_0();
            case 0x0f:
                return new DCONST_1();
            case 0x10:
                return new BIPUSH();
            case 0x11:
                return new SIPUSH();
            // case 0x12:
            // return &LDC{}
            // case 0x13:
            // return &LDC_W{}
            // case 0x14:
            // return &LDC2_W{}
            case 0x15:
                return new ILOAD();
            case 0x16:
                return new LLOAD();
            case 0x17:
                return new FLOAD();
            case 0x18:
                return new DLOAD();
            case 0x19:
                return new ALOAD();
            case 0x1a:
                return new ILOAD_0();
            case 0x1b:
                return new ILOAD_1();
            case 0x1c:
                return new ILOAD_2();
            case 0x1d:
                return new ILOAD_3();
            case 0x1e:
                return new LLOAD_0();
            case 0x1f:
                return new LLOAD_1();
            case 0x20:
                return new LLOAD_2();
            case 0x21:
                return new LLOAD_3();
            case 0x22:
                return new FLOAD_0();
            case 0x23:
                return new FLOAD_1();
            case 0x24:
                return new FLOAD_2();
            case 0x25:
                return new FLOAD_3();
            case 0x26:
                return new DLOAD_0();
            case 0x27:
                return new DLOAD_1();
            case 0x28:
                return new DLOAD_2();
            case 0x29:
                return new DLOAD_3();
            case 0x2a:
                return new ALOAD_0();
            case 0x2b:
                return new ALOAD_1();
            case 0x2c:
                return new ALOAD_2();
            case 0x2d:
                return new ALOAD_3();
            // case 0x2e:
            // return iaload
            // case 0x2f:
            // return laload
            // case 0x30:
            // return faload
            // case 0x31:
            // return daload
            // case 0x32:
            // return aaload
            // case 0x33:
            // return baload
            // case 0x34:
            // return caload
            // case 0x35:
            // return saload
            case 0x36:
                return new ISTORE();
            case 0x37:
                return new LSTORE();
            case 0x38:
                return new FSTORE();
            case 0x39:
                return new DSTORE();
            case 0x3a:
                return new ASTORE();
            case 0x3b:
                return new ISTORE_0();
            case 0x3c:
                return new ISTORE_1();
            case 0x3d:
                return new ISTORE_2();
            case 0x3e:
                return new ISTORE_3();
            case 0x3f:
                return new LSTORE_0();
            case 0x40:
                return new LSTORE_1();
            case 0x41:
                return new LSTORE_2();
            case 0x42:
                return new LSTORE_3();
            case 0x43:
                return new FSTORE_0();
            case 0x44:
                return new FSTORE_1();
            case 0x45:
                return new FSTORE_2();
            case 0x46:
                return new FSTORE_3();
            case 0x47:
                return new DSTORE_0();
            case 0x48:
                return new DSTORE_1();
            case 0x49:
                return new DSTORE_2();
            case 0x4a:
                return new DSTORE_3();
            case 0x4b:
                return new ASTORE_0();
            case 0x4c:
                return new ASTORE_1();
            case 0x4d:
                return new ASTORE_2();
            case 0x4e:
                return new ASTORE_3();
            // case 0x4f:
            // return iastore
            // case 0x50:
            // return lastore
            // case 0x51:
            // return fastore
            // case 0x52:
            // return dastore
            // case 0x53:
            // return aastore
            // case 0x54:
            // return bastore
            // case 0x55:
            // return castore
            // case 0x56:
            // return sastore
            case 0x57:
                return new POP();
            case 0x58:
                return new POP2();
            case 0x59:
                return new DUP();
            case 0x5a:
                return new DUP_X1();
            case 0x5b:
                return new DUP_X2();
            case 0x5c:
                return new DUP2();
            case 0x5d:
                return new DUP2_X1();
            case 0x5e:
                return new DUP2_X2();
            case 0x5f:
                return new SWAP();
            case 0x60:
                return new IADD();
            case 0x61:
                return new LADD();
            case 0x62:
                return new FADD();
            case 0x63:
                return new DADD();
            case 0x64:
                return new ISUB();
            case 0x65:
                return new LSUB();
            case 0x66:
                return new FSUB();
            case 0x67:
                return new DSUB();
            case 0x68:
                return new IMUL();
            case 0x69:
                return new LMUL();
            case 0x6a:
                return new FMUL();
            case 0x6b:
                return new DMUL();
            case 0x6c:
                return new IDIV();
            case 0x6d:
                return new LDIV();
            case 0x6e:
                return new FDIV();
            case 0x6f:
                return new DDIV();
            case 0x70:
                return new IREM();
            case 0x71:
                return new LREM();
            case 0x72:
                return new FREM();
            case 0x73:
                return new DREM();
            case 0x74:
                return new INEG();
            case 0x75:
                return new LNEG();
            case 0x76:
                return new FNEG();
            case 0x77:
                return new DNEG();
            case 0x78:
                return new ISHL();
            case 0x79:
                return new LSHL();
            case 0x7a:
                return new ISHR();
            case 0x7b:
                return new LSHR();
            case 0x7c:
                return new IUSHR();
            case 0x7d:
                return new LUSHR();
            case 0x7e:
                return new IAND();
            case 0x7f:
                return new LAND();
            case (byte) 0x80:
                return new IOR();
            case (byte) 0x81:
                return new LOR();
            case (byte) 0x82:
                return new IXOR();
            case (byte) 0x83:
                return new LXOR();
            case (byte) 0x84:
                return new IINC();
            case (byte) 0x85:
                return new I2L();
            case (byte) 0x86:
                return new I2F();
            case (byte) 0x87:
                return new I2D();
            case (byte) 0x88:
                return new L2I();
            case (byte) 0x89:
                return new L2F();
            case (byte) 0x8a:
                return new L2D();
            case (byte) 0x8b:
                return new F2I();
            case (byte) 0x8c:
                return new F2L();
            case (byte) 0x8d:
                return new F2D();
            case (byte) 0x8e:
                return new D2I();
            case (byte) 0x8f:
                return new D2L();
            case (byte) 0x90:
                return new D2F();
            case (byte) 0x91:
                return new I2B();
            case (byte) 0x92:
                return new I2C();
            case (byte) 0x93:
                return new I2S();
            case (byte) 0x94:
                return new LCMP();
            case (byte) 0x95:
                return new FCMPL();
            case (byte) 0x96:
                return new FCMPG();
            case (byte) 0x97:
                return new DCMPL();
            case (byte) 0x98:
                return new DCMPG();
            case (byte) 0x99:
                return new IFEQ();
            case (byte) 0x9a:
                return new IFNE();
            case (byte) 0x9b:
                return new IFLT();
            case (byte) 0x9c:
                return new IFGE();
            case (byte) 0x9d:
                return new IFGT();
            case (byte) 0x9e:
                return new IFLE();
            case (byte) 0x9f:
                return new IF_ICMPEQ();
            case (byte) 0xa0:
                return new IF_ICMPNE();
            case (byte) 0xa1:
                return new IF_ICMPLT();
            case (byte) 0xa2:
                return new IF_ICMPGE();
            case (byte) 0xa3:
                return new IF_ICMPGT();
            case (byte) 0xa4:
                return new IF_ICMPLE();
            case (byte) 0xa5:
                return new IF_ACMPEQ();
            case (byte) 0xa6:
                return new IF_ACMPNE();
            case (byte) 0xa7:
                return new GOTO();
            // case 0xa8:
            // return &JSR{}
            // case 0xa9:
            // return &RET{}
            case (byte) 0xaa:
                return new TABLE_SWITCH();
            case (byte) 0xab:
                return new LOOKUP_SWITCH();
            // case 0xac:
            // return ireturn
            // case 0xad:
            // return lreturn
            // case 0xae:
            // return freturn
            // case 0xaf:
            // return dreturn
            // case 0xb0:
            // return areturn
            // case 0xb1:
            // return _return
            //case 0xb2:
            //return &GET_STATIC{}
            // case 0xb3:
            // return &PUT_STATIC{}
            // case 0xb4:
            // return &GET_FIELD{}
            // case 0xb5:
            // return &PUT_FIELD{}
            //case 0xb6:
            //return &INVOKE_VIRTUAL{}
            // case 0xb7:
            // return &INVOKE_SPECIAL{}
            // case 0xb8:
            // return &INVOKE_STATIC{}
            // case 0xb9:
            // return &INVOKE_INTERFACE{}
            // case 0xba:
            // return &INVOKE_DYNAMIC{}
            // case 0xbb:
            // return &NEW{}
            // case 0xbc:
            // return &NEW_ARRAY{}
            // case 0xbd:
            // return &ANEW_ARRAY{}
            // case 0xbe:
            // return arraylength
            // case 0xbf:
            // return athrow
            // case 0xc0:
            // return &CHECK_CAST{}
            // case 0xc1:
            // return &INSTANCE_OF{}
            // case 0xc2:
            // return monitorenter
            // case 0xc3:
            // return monitorexit
            case (byte) 0xc4:
                return new WIDE();
            // case 0xc5:
            // return &MULTI_ANEW_ARRAY{}
            case (byte) 0xc6:
                return new IFNULL();
            case (byte) 0xc7:
                return new IFNONNULL();
            case (byte) 0xc8:
                return new GOTO_W();
            // case 0xc9:
            // return &JSR_W{}
            // case 0xca: breakpoint
            // case 0xfe: impdep1
            // case 0xff: impdep2
            default:
                return null;

        }

    }

}

Interpret.java

//指令集解釋器
class Interpret {

    Interpret(MemberInfo m) {
        CodeAttribute codeAttr = m.codeAttribute();
        int maxLocals = codeAttr.maxLocals();
        int maxStack = codeAttr.maxStack();
        byte[] byteCode = codeAttr.data();
        Thread thread = new Thread();
        Frame frame = thread.newFrame(maxLocals, maxStack);
        thread.pushFrame(frame);
        loop(thread, byteCode);
    }

    private void loop(Thread thread, byte[] byteCode) {
        Frame frame = thread.popFrame();
        BytecodeReader reader = new BytecodeReader();

        while (true) {
            //循環(huán)
            int pc = frame.nextPC();
            thread.setPC(pc);
            //decode
            reader.reset(byteCode, pc);
            byte opcode = reader.readByte();
            Instruction inst = Factory.newInstruction(opcode);
            if (null == inst) {
                System.out.println("寄存器(指令)尚未實(shí)現(xiàn) " + byteToHexString(new byte[]{opcode}));
                break;
            }
            inst.fetchOperands(reader);
            frame.setNextPC(reader.pc());
            System.out.println("寄存器(指令):" + byteToHexString(new byte[]{opcode}) + " -> " + inst.getClass().getSimpleName() + " => 局部變量表:" + JSON.toJSONString(frame.operandStack().getSlots()) + " 操作數(shù)棧:" + JSON.toJSONString(frame.operandStack().getSlots()));            //exec
            inst.execute(frame);
        }

    }

    private static String byteToHexString(byte[] codes) {
        StringBuilder sb = new StringBuilder();
        sb.append("0x");
        for (byte b : codes) {
            int value = b & 0xFF;
            String strHex = Integer.toHexString(value);
            if (strHex.length() < 2) {
                strHex = "0" + strHex;
            }
            sb.append(strHex);
        }
        return sb.toString();
    }

}

HelloWorld.java

package org.itstack.demo.test;

public class HelloWorld {
    
    public static void main(String[] args) {
        int sum = 0;
        for (int i = 1; i <= 100; i++) {
            sum += i;
        }
        System.out.println(sum);
    }
    
}

測(cè)試結(jié)果 {此時(shí)還不能輸出結(jié)果,但是在操作數(shù)據(jù)棧中已經(jīng)可以看到結(jié)果:5050}

"C:\Program Files\Java\jdk1.8.0_161\bin\java.exe" "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2018.3.1\lib\idea_rt.jar=61887:D:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2018.3.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_161\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\rt.jar;E:\itstack\git\istack-demo\itstack-demo-jvm\itstack-demo-jvm-05\target\classes;D:\Program Files (x86)\apache-maven-2.2.1\repository\com\beust\jcommander\1.72\jcommander-1.72.jar;D:\Program Files (x86)\apache-maven-2.2.1\repository\org\projectlombok\lombok\1.18.0\lombok-1.18.0.jar;D:\Program Files (x86)\apache-maven-2.2.1\repository\com\alibaba\fastjson\1.2.40\fastjson-1.2.40.jar" org.itstack.demo.jvm.Main -Xjre "C:\Program Files\Java\jdk1.8.0_161\jre" E:\itstack\git\istack-demo\itstack-demo-jvm\itstack-demo-jvm-05\target\test-classes\org\itstack\demo\test\HelloWorld
classpath:org.itstack.demo.jvm.classpath.Classpath@4bf558aa class:E:\itstack\git\istack-demo\itstack-demo-jvm\itstack-demo-jvm-05\target\test-classes\org\itstack\demo\test\HelloWorld args:null
寄存器(指令):0x03 -> ICONST_0 => 局部變量表:[{"num":0},{"num":0}] 操作數(shù)棧:[{"num":0},{"num":0}]
寄存器(指令):0x3c -> ISTORE_1 => 局部變量表:[{"num":0},{"num":0}] 操作數(shù)棧:[{"num":0},{"num":0}]
寄存器(指令):0x04 -> ICONST_1 => 局部變量表:[{"num":0},{"num":0}] 操作數(shù)棧:[{"num":0},{"num":0}]
寄存器(指令):0x3d -> ISTORE_2 => 局部變量表:[{"num":1},{"num":0}] 操作數(shù)棧:[{"num":1},{"num":0}]
寄存器(指令):0x1c -> ILOAD_2 => 局部變量表:[{"num":1},{"num":0}] 操作數(shù)棧:[{"num":1},{"num":0}]
寄存器(指令):0x10 -> BIPUSH => 局部變量表:[{"num":1},{"num":0}] 操作數(shù)棧:[{"num":1},{"num":0}]
寄存器(指令):0xa3 -> IF_ICMPGT => 局部變量表:[{"num":1},{"num":100}] 操作數(shù)棧:[{"num":1},{"num":100}]
寄存器(指令):0x1b -> ILOAD_1 => 局部變量表:[{"num":1},{"num":100}] 操作數(shù)棧:[{"num":1},{"num":100}]
寄存器(指令):0x1c -> ILOAD_2 => 局部變量表:[{"num":0},{"num":100}] 操作數(shù)棧:[{"num":0},{"num":100}]

... ...

寄存器(指令):0x60 -> IADD => 局部變量表:[{"num":4950},{"num":100}] 操作數(shù)棧:[{"num":4950},{"num":100}]
寄存器(指令):0x3c -> ISTORE_1 => 局部變量表:[{"num":5050},{"num":100}] 操作數(shù)棧:[{"num":5050},{"num":100}]
寄存器(指令):0x84 -> IINC => 局部變量表:[{"num":5050},{"num":100}] 操作數(shù)棧:[{"num":5050},{"num":100}]
寄存器(指令):0xa7 -> GOTO => 局部變量表:[{"num":5050},{"num":100}] 操作數(shù)棧:[{"num":5050},{"num":100}]
寄存器(指令):0x1c -> ILOAD_2 => 局部變量表:[{"num":5050},{"num":100}] 操作數(shù)棧:[{"num":5050},{"num":100}]
寄存器(指令):0x10 -> BIPUSH => 局部變量表:[{"num":101},{"num":100}] 操作數(shù)棧:[{"num":101},{"num":100}]
寄存器(指令):0xa3 -> IF_ICMPGT => 局部變量表:[{"num":101},{"num":100}] 操作數(shù)棧:[{"num":101},{"num":100}]
寄存器(指令)尚未實(shí)現(xiàn) 0xb2

Process finished with exit code 0

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章

    国产午夜在线精品视频| 国产精品欧美一级免费| 日韩中文字幕免费在线视频| 色婷婷激情五月天丁香| 欧美特色特黄一级大黄片| 国产午夜福利在线观看精品| 婷婷色国产精品视频一区| 亚洲中文字幕有码在线观看| 91日韩欧美中文字幕| 亚洲欧美日韩国产综合在线| 欧美成人免费一级特黄| 国产精品午夜福利在线观看| 日韩精品日韩激情日韩综合| 国产精品香蕉免费手机视频| 日韩欧美黄色一级视频| 欧美精品一区久久精品| 欧美av人人妻av人人爽蜜桃| 微拍一区二区三区福利| 欧美人与动牲交a精品| 日本黄色录像韩国黄色录像| 午夜国产福利在线播放| 日本精品啪啪一区二区三区| 有坂深雪中文字幕亚洲中文| 美女被后入福利在线观看| 国产免费一区二区三区av大片 | 国产对白老熟女正在播放| 免费人妻精品一区二区三区久久久| 亚洲熟妇熟女久久精品 | 国产精品欧美一区二区三区| 麻豆印象传媒在线观看| 亚洲精品欧美精品一区三区| 人妻少妇av中文字幕乱码高清| 麻豆看片麻豆免费视频| 国产中文字幕久久黄色片| 亚洲av熟女一区二区三区蜜桃 | 亚洲综合色在线视频香蕉视频 | 亚洲欧美日韩色图七区| 国产精品尹人香蕉综合网| 福利视频一区二区在线| 国产精品一区日韩欧美| 日本午夜福利视频免费观看|