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…