Learning By Doing.java
最近開了個新坑, 目的是用 Java 8 實現一個簡單的解釋型 JVM. 目前零零散散提交了 100 多 commits. 最終的目標是 自舉.
目前進度大概 60%, 基本的 ClassFile 解析, 類加載, 字節碼執行, 方法調用, 對象實例化, 多態, 接口基本可用.git
mini-jvm 項目的動機.github
寫此文的目的.bash
在實現的過程當中, 已力保代碼簡單, 可讀, 可測. 目前爲止代碼 5000 行出頭, 竊覺得, 對於想了解 JVM 基本原理的同窗是個不錯的入門項目. 在此基礎上, 爲了便於理解一些概念, 好比基於棧的虛擬機實現原理, 會特地實現一個邊緣特性用來快速理解.數據結構
對 JVM 字節碼執行引擎稍有了解的話, 應該對棧幀有所瞭解jvm
棧幀(Stack Frame)是用於支持虛擬機進行方法調用和方法執行的數據結構 棧幀隨着方法調用而建立,隨着方法結束而銷燬,棧幀的存儲空間分配在 Java 虛擬機棧中,每一個棧幀擁有本身的局部變量表(Local Variables)操做數棧(Operand Stack)ui
若是嘗試用過 javap -v classfile , method 區塊亦有所體現.spa
下面看一個簡單的例子3d
public class Hello {
public static int return1() {
return 1;
}
}
複製代碼
編譯並使用code
cat <<EOF > Hello.java
public class Hello {
public static int return1() {
return 1;
}
}
EOF
# 很明顯, 若是 return1 方法被調用, 返回結果必定是 1 .
javac Hello.java
javap -v Hello.class
複製代碼
輸出較長, 只摘抄方法部分以下
public static int return1();
descriptor: ()I
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=0, args_size=0
0: iconst_1
1: ireturn
複製代碼
stack=1 即此方法棧操做數棧大小爲 1 locals=0 即此方法局部變量表大小爲 0 args_size 即此方法參數個數爲 0
0: iconst_1
1: ireturn
複製代碼
這便是該方法的字節碼
0: iconst_1 , 表示該方法指令集 0 位置 的指令爲 iconst_1 , iconst_1 的含義是 將 int 值 1 push 到操做數棧.
1: ireturn , 表示該方法指令集 1 位置 的指令爲 ireturn , ireturn 的含義是, 將當前操做數棧棧頂 int 類型值彈出, 而且把當前棧幀彈出, 並將從操做數棧彈出的 int 類型值 push 到當前棧幀的操做數棧.
相似 iconst_1 這種指令, JVM 規範定義了 200 + 個.
爲了方便理解. 項目實現了一個簡單的類彙編語言來描述字節碼,並解釋執行.
return1 1 0 0
0 iconst_1
1 ireturn
複製代碼
對比上方 javap -v 的輸出, 去除了一些冗餘信息.
下爲實際截圖
稍複雜一點的 sum10
更復雜一點的 sumN
簡介到此告一段落, 更多信息可往 github repo 瞭解.
如有興趣參與, 務必聯繫我, 虛左以待.
聯繫方式
vx: echo "Z3V4aW5na2VfCg==" | base64 -d
mail: echo "YWRtaW5AZ3V4aW5na2UuY29tCg==" | base64 -d
項目地址
github: github.com/guxingke/mi…