diff --git a/ldebug.c b/ldebug.c index 3ea6367f..93a935a5 100644 --- a/ldebug.c +++ b/ldebug.c @@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 2.151 2017/12/28 15:42:57 roberto Exp roberto $ +** $Id: ldebug.c,v 2.152 2018/01/10 12:02:35 roberto Exp roberto $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -143,7 +143,7 @@ LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { L->basehookcount = count; resethookcount(L); L->hookmask = cast_byte(mask); - if (mask & (LUA_MASKLINE | LUA_MASKCOUNT)) + if (mask) settraps(L->ci); /* to trace inside 'luaV_execute' */ } diff --git a/ldo.c b/ldo.c index 6ab57f8e..d627941c 100644 --- a/ldo.c +++ b/ldo.c @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 2.188 2018/01/28 13:39:52 roberto Exp roberto $ +** $Id: ldo.c,v 2.189 2018/01/29 16:21:35 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -294,19 +294,21 @@ void luaD_hook (lua_State *L, int event, int line) { } -static void hookcall (lua_State *L, CallInfo *ci, int istail) { - int hook; - ci->u.l.trap = 1; - if (!(L->hookmask & LUA_MASKCALL)) - return; /* some other hook */ +/* +** Executes a call hook for Lua functions. This function is called +** whenever 'hookmask' is not zero, so it checks whether call hooks are +** active. Also, this function can be called when resuming a function, +** so it checks whether the function is in its first instruction. +*/ +void luaD_hookcall (lua_State *L, CallInfo *ci) { + Proto *p = clLvalue(s2v(ci->func))->p; + int hook = (ci->callstatus & CIST_TAIL) ? LUA_HOOKTAILCALL : LUA_HOOKCALL; + ci->u.l.trap = 1; /* there may be other hooks */ + if (!(L->hookmask & LUA_MASKCALL) || /* some other hook? */ + ci->u.l.savedpc != p->code) /* not 1st instruction? */ + return; /* don't call hook */ L->top = ci->top; /* prepare top */ ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */ - if (istail) { - ci->callstatus |= CIST_TAIL; - hook = LUA_HOOKTAILCALL; - } - else - hook = LUA_HOOKCALL; luaD_hook(L, hook, -1); ci->u.l.savedpc--; /* correct 'pc' */ } @@ -427,8 +429,6 @@ void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int narg1) { L->top = func + narg1; /* set top */ luaT_adjustvarargs(L, nfixparams, narg1 - 1); } - if (L->hookmask) - hookcall(L, ci, 1); } @@ -483,8 +483,6 @@ void luaD_call (lua_State *L, StkId func, int nresults) { ci->callstatus = 0; if (p->is_vararg) luaT_adjustvarargs(L, nfixparams, narg); /* may invoke GC */ - if (L->hookmask) - hookcall(L, ci, 0); luaV_execute(L, ci); /* run the function */ break; } diff --git a/ldo.h b/ldo.h index 50f79242..44e3af20 100644 --- a/ldo.h +++ b/ldo.h @@ -1,5 +1,5 @@ /* -** $Id: ldo.h,v 2.38 2017/12/11 12:43:40 roberto Exp roberto $ +** $Id: ldo.h,v 2.39 2018/01/10 19:19:27 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -48,6 +48,7 @@ typedef void (*Pfunc) (lua_State *L, void *ud); LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, const char *mode); LUAI_FUNC void luaD_hook (lua_State *L, int event, int line); +LUAI_FUNC void luaD_hookcall (lua_State *L, CallInfo *ci); LUAI_FUNC void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int n); LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); diff --git a/lvm.c b/lvm.c index d6380e4b..d9814b62 100644 --- a/lvm.c +++ b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 2.335 2018/01/27 16:56:33 roberto Exp roberto $ +** $Id: lvm.c,v 2.336 2018/01/29 16:21:35 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -832,8 +832,11 @@ void luaV_execute (lua_State *L, CallInfo *ci) { TValue *k; StkId base; const Instruction *pc; - int trap = ci->u.l.trap; + int trap; tailcall: + trap = L->hookmask; + if (trap) + luaD_hookcall(L, ci); cl = clLvalue(s2v(ci->func)); k = cl->p->k; base = ci->func + 1;