探索Lua5.2内部实现:虚拟机指令(7) 关系和逻辑指令
原文
JMP执行一个跳转,sBx表示跳转的偏移位置,被加到当前指向下一指令的指令指针上。如果sBx为0,表示没有任何跳转;1表示跳过下一个指令;-1表示重新执行当前指令。如果A>0,表示需要关闭所有从寄存器A+1开始的所有local变量。实际执行的关闭操作只对upvalue有效。
JMP最直接的使用就是对应lua5.2新加入的goto语句:
name args desc OP_EQA B Cif ((RK(B) == RK(C)) ~= A) then pc++OP_LTA B Cif ((RK(B) < RK(C)) ~= A) then pc++OP_LEA B Cif ((RK(B) <= RK(C)) ~= A) then pc++关系指令对RK(B)和RK(C)进行比较,然后将比较结果与A指定的boolean值进行比较,来决定最终的boolean值。A在这里为每个关系指令提供了两种比较目标,满足和不满足。比如OP_LT何以用来实现“<”和“>”。
name args desc OP_TESTA Cif not (R(A) <=> C) then pc++OP_TESTSETA B Cif (R(B) <=> C) then R(A) := R(B) else pc++逻辑指令用于实现and和or逻辑运算符,或者在条件语句中判断一个寄存器。TESTSET将寄存器B转化成一个boolean值,然后与C进行比较。如果不相等,跳过后面的JMP指令。否则将寄存器B的值赋给寄存器A,然后继续执行。TEST是TESTSET的简化版,不需要赋值操作。
if b then a = celse a = bend