本章节继续学习指令集和解释器。
类型转换指令
类型转换指令大致对应Java语言中的基本类型强制转换操作。按照被转换变量的类型,类型转换指令可以分为4种:i2x系列指令把int变量强制转换成其他类型;l2x系列指令把long变量强制转换成其他类型;f2x系列指令把float变量强制转换成其他类型;d2x系列指令把double变量强制转换成其他类型。该指令实现代码位于/instructions/conversions包下,下面以d2x系类指令为例来学习下,其代码位于d2x.go文件中:
|
|
比较指令
比较指令可以分为两类:一类将比较结果推入操作数栈,一类根据比较结果跳转。比较指令时编译器实现if-else、for、while等语句的基石。该系列指令实现代码位于/instructions/comparisons包下。
lcmp指令
lcmp指令用于比较long变量,其实现代码位于lcmp.go文件中:
fcmp<op>和dcmp<op>指令
fcmpg和fcmpl指令用于比较float变量。由于浮点数计算有可能产生NaN值,所以比较两个浮点数时除了大于、等于、小于之外,还有第4种结果:无法比较。fcmpg和fcmpl指令的区别就在于对第4种结果的定义。其实现代码位于fcmp.go文件中:
dcmpg和dcmpl指令用来比较double变量,和fcmp指令实现类似,相关代码参照dcmp.go文件
if<cond>指令
if<cond>指令把操作数栈顶的int变量弹出,然后跟0进行比较,满足条件则跳转。假设从栈顶弹出的变量时x,则指令执行跳转操作的条件如下:
- ifeq: x == 0
- ifne: x != 0
- iflt: x < 0
- ifle: x <= 0
- ifgt: x > 0
- ifge: x >= 0
该指令实现代码位于ifcond.go文件中,下面以ifeq为例来看下代码:
真正的跳转逻辑在base.Branch()函数中,因为这个函数在很多指令中都会用到,所以把它定义在/base/branch_logic.go文件中,其代码如下:
上面Thread()和SetNextPC()都还没定义,暂时编译不过没关系,后面会补充。
if_icmp<cond>指令
if_icmp<cond>指令把栈顶的两个int变量弹出,然后进行比较,满足条件则跳转。跳转条件和if<cond>指令类似,下面以if_icmpne为例来演示下,相关嗲吗位于if_icmp.go文件中:
if_acmp<cond>指令
if_acmpeq和if_acmpne指令把栈顶的两个引用弹出,根据引用是否相同进行跳转。其实现代码位于if_acmp.go文件中:
下节继续。。。