【问题标题】:How to comprehend that "lua_Hook is called when it jumps back in the code(This event only happens while Lua is executing a Lua function.)"?如何理解“lua_Hook在代码中跳转时被调用(该事件仅在Lua执行Lua函数时发生。)”?
【发布时间】:2021-03-26 00:31:19
【问题描述】:

根据文档 (https://www.lua.org/manual/5.3/manual.html#lua_sethook),上面写着[empasise mine]:

参数 f 是钩子函数。掩码指定在哪些事件上 将调用钩子:它由常量的按位或形成 LUA_MASKCALL、LUA_MASKRET、LUA_MASKLINE 和 LUA_MASKCOUNT。伯爵 参数仅在掩码包含 LUA_MASKCOUNT 时才有意义。为了 每个事件,钩子被调用如下:

调用钩子:在解释器调用函数时调用。这 在 Lua 进入新函数之后,在 函数获取它的参数。

返回钩子:当 解释器从函数返回。钩子在之前被调用 Lua 离开了这个函数。没有标准的方法来访问这些值 由函数返回。

线路钩子:当 解释器即将开始执行新的代码行,或者 当它在代码中跳回时(甚至到同一行)。 (本次活动 仅在 Lua 执行 Lua 函数时发生。)

如何理解lua_Hook在代码中跳转时被调用(该事件仅在Lua执行Lua函数时发生?

【问题讨论】:

  • 可能这意味着一个 C 函数(从 Lua 代码调用,例如 math.sin)已经返回,并且 Lua 代码继续运行。

标签: lua


【解决方案1】:

我们可以看源码(Lua 5.4):

int luaG_traceexec (lua_State *L, const Instruction *pc) {
  -- some parts removed
  if (mask & LUA_MASKLINE) {
    if (npci == 0 ||  /* call linehook when enter a new function, */
        pc <= L->oldpc ||  /* when jump back (loop), or when */
        changedline(p, pcRel(L->oldpc, p), npci)) {  /* enter new line */
      int newline = luaG_getfuncline(p, npci);
      luaD_hook(L, LUA_HOOKLINE, newline, 0, 0);  /* call line hook */
    }
  }
  return 1;  /* keep 'trap' on */
}

可以看出,LUA_HOOKLINE在三种情况下被调用:(1)进入新函数,(2)跳回(循环),或者(3)进入新行。

通过调用changedline来检查“输入新行”:

static int changedline (const Proto *p, int oldpc, int newpc) {
  while (oldpc++ < newpc) {
    if (p->lineinfo[oldpc] != 0)
      return (luaG_getfuncline(p, oldpc - 1) != luaG_getfuncline(p, newpc));
  }
  return 0;  /* no line changes in the way */
}

如果新指令与前一条指令位于不同的行,则返回 true。

luaG_getfuncline 如果有可用的调试信息,则获取指令的行号。正在检查的函数是基于当前调用信息值的活动 lua 函数。

【讨论】:

  • 感谢您的详细解释。如何理解 lua_Hook 在代码中跳转时被调用(我认为它与pc &lt;= L-&gt;oldpc 有一定的关系,这是您强调的)?但我知道我并不完全理解它。
  • pc(程序计数器)指向要执行的下一条指令。如果它小于/等于上一条/当前指令,则它是一个跳转回,这发生在同一行上的循环中,例如,for i = 1, 3 do print(i) end 将获得 3 行钩子调用。
  • 我明白了。在您的帮助下,我对这个问题的理解处于不同的水平。我曾尝试运行一段代码 sn-p(如前所述),但在您向我解释之前我并不完全理解它。
猜你喜欢
  • 2011-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-04
  • 2013-07-28
  • 2021-07-23
  • 2017-11-07
相关资源
最近更新 更多