Lua5.3 VM 分析(四)分支和跳转

Lua5.3 VM 分析(四)分支和跳转

Lua VM 定义了 OP_EQ、OP_LT、OP_LE、OP_TEST、OP_TESTSET 五种分支操作。

这五个分支指令必须与 之后的 跳转指令 JMP 看做一个整体解释。也就是说:当条件成立时,继续运行;条件不成立时,跳转到指定位置。

如果条件成立跳转到L1, 否则跳转到L2: 
L1: 
    success() 
    jmp exit 
L2: 
    fail() 
    jmp exit
 exit: 
    exit()

OP_JMP

OP_JMP 可以单独使用, 做无条件跳转指令。跳转地址使用的是相对量,负数表示向前跳转。0 表示下一条指令。

vmcase(OP_JMP) {
        dojump(ci, i, 0);
        vmbreak;
      }

define dojump(ci,i,e) \
  { int a = GETARG_A(i); \
if (a > 0) luaF_close(L, ci->u.l.base + a - 1); \
ci->u.l.savedpc += GETARG_sBx(i) + e; }

define donextjump(ci)   { i = *ci->u.l.savedpc; dojump(ci, i, 1); }

无条件跳转和条件跳转分别用 dojump 宏 与 donextjump 两个宏实现。
donextjump 读出下一条指令,必定是JMP。

dojump 宏负责 指令的偏移 ( ci->u.l.savedpc += GETARG_sBx(i) + e; )。
当 a (Instruction 的 A 部分)大于 0 时,调用luaF_close 函数关闭 A 层次的 upvalue 。

OP_EQ

  vmcase(OP_EQ) {
TValue *rb = RKB(i);
TValue *rc = RKC(i);
Protect(
  if (cast_int(luaV_equalobj(L, rb, rc)) != GETARG_A(i))
ci->u.l.savedpc++;
  else
donextjump(ci);
)
vmbreak;
  }

利用 luaV_equalobj 函数判断条件是否成立,当不成立时,执行 donextjump 。反则根据 类型不同比较算法不同。

int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
  const TValue *tm;
  if (ttype(t1) != ttype
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值