void luaG_traceexec (lua_State *L) { CallInfo *ci = L->ci; lu_byte mask = L->hookmask; int counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT)); if (counthook) resethookcount(L); /* reset count */ else if (!(mask & LUA_MASKLINE)) return; /* no line hook and count != 0; nothing to be done */ if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */ ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ return; /* do not call hook again (VM yielded, so it did not move) */ } if (counthook) luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */ if (mask & LUA_MASKLINE) { Proto *p = ci_func(ci)->p; int npc = pcRel(ci->u.l.savedpc, p); int newline = getfuncline(p, npc); if (npc == 0 || /* call linehook when enter a new function, */ ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */ newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */ luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */ } L->oldpc = ci->u.l.savedpc; if (L->status == LUA_YIELD) { /* did hook yield? */ if (counthook) L->hookcount = 1; /* undo decrement to zero */ ci->u.l.savedpc--; /* undo increment (resume will increment it again) */ ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ ci->func = L->top - 1; /* protect stack below results */ luaD_throw(L, LUA_YIELD); } }
/* 内部栈跟踪 * L 虚拟机状态 */ static void traceexec (lua_State *L) { CallInfo *ci = L->ci; /* 获取调用链表 */ lu_byte mask = L->hookmask; /* hook掩码 */ /* 如果hook计数等于0,则重新获取hook的数量 */ int counthook = ((mask & LUA_MASKCOUNT) && L->hookcount == 0); /* 如果计数不为空,则重新设置 */ if (counthook) resethookcount(L); /* reset count */ /* 最后一次调用hook函数 */ if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */ /* 取消hook调用掩码 */ ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ return; /* do not call hook again (VM yielded, so it did not move) */ } /* 如果hook计数不为空,则调用hook函数 */ if (counthook) luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */ /* 行hook */ if (mask & LUA_MASKLINE) { Proto *p = ci_func(ci)->p; int npc = pcRel(ci->u.l.savedpc, p); int newline = getfuncline(p, npc); if (npc == 0 || /* call linehook when enter a new function, */ ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */ newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */ luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */ } /* 保存要返回的pc寄存器的值 */ L->oldpc = ci->u.l.savedpc; /* 如果虚拟机的状态是挂起 */ if (L->status == LUA_YIELD) { /* did hook yield? */ if (counthook) L->hookcount = 1; /* undo decrement to zero */ ci->u.l.savedpc--; /* undo increment (resume will increment it again) */ ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ ci->func = L->top - 1; /* protect stack below results */ luaD_throw(L, LUA_YIELD); } }
static void traceexec (lua_State *L) { CallInfo *ci = L->ci; lu_byte mask = L->hookmask; if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) { resethookcount(L); luaD_hook(L, LUA_HOOKCOUNT, -1); } if (mask & LUA_MASKLINE) { Proto *p = ci_func(ci)->p; int npc = pcRel(ci->u.l.savedpc, p); int newline = getfuncline(p, npc); if (npc == 0 || /* call linehook when enter a new function, */ ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */ newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */ luaD_hook(L, LUA_HOOKLINE, newline); } L->oldpc = ci->u.l.savedpc; if (L->status == LUA_YIELD) { /* did hook yield? */ ci->u.l.savedpc--; /* undo increment (resume will increment it again) */ luaD_throw(L, LUA_YIELD); } }
l_noret luaG_errormsg (lua_State *L) { if (L->errfunc != 0) { /* is there an error handling function? */ StkId errfunc = restorestack(L, L->errfunc); setobjs2s(L, L->top, L->top - 1); /* move argument */ setobjs2s(L, L->top - 1, errfunc); /* push function */ L->top++; /* assume EXTRA_STACK */ luaD_call(L, L->top - 2, 1, 0); /* call it */ } #if LUA_TILDE_DEBUGGER if (L->hookmask & LUA_MASKERROR) luaD_hook(L, LUA_HOOKERROR, -1); #endif /* LUA_TILDE_DEBUGGER */ luaD_throw(L, LUA_ERRRUN); }
l_noret luaG_runerror (lua_State *L, const char *fmt, ...) { CallInfo *ci = L->ci; const char *msg; va_list argp; va_start(argp, fmt); msg = luaO_pushvfstring(L, fmt, argp); /* format message */ va_end(argp); if (isLua(ci)) /* if Lua function, add source:line information */ luaG_addinfo(L, msg, ci_func(ci)->p->source, currentline(ci)); #if LUA_TILDE_DEBUGGER if (L->hookmask & LUA_MASKERROR) luaD_hook(L, LUA_HOOKERROR, -1); #endif /* LUA_TILDE_DEBUGGER */ luaG_errormsg(L); }