mirror of https://github.com/rusefi/lua.git
Bug: Call hook may be called twice when count hook yields
Took the opportunity and moved the code that controls call hooks in 'luaV_execute' into a function.
This commit is contained in:
parent
6b51133a98
commit
1b3f507f62
22
ldebug.c
22
ldebug.c
|
@ -865,6 +865,28 @@ static int changedline (const Proto *p, int oldpc, int newpc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Traces Lua calls. If code is running the first instruction of a function,
|
||||||
|
** and function is not vararg, and it is not coming from an yield,
|
||||||
|
** calls 'luaD_hookcall'. (Vararg functions will call 'luaD_hookcall'
|
||||||
|
** after adjusting its variable arguments; otherwise, they could call
|
||||||
|
** a line/count hook before the call hook. Functions coming from
|
||||||
|
** an yield already called 'luaD_hookcall' before yielding.)
|
||||||
|
*/
|
||||||
|
int luaG_tracecall (lua_State *L) {
|
||||||
|
CallInfo *ci = L->ci;
|
||||||
|
Proto *p = ci_func(ci)->p;
|
||||||
|
ci->u.l.trap = 1; /* ensure hooks will be checked */
|
||||||
|
if (ci->u.l.savedpc == p->code) { /* first instruction (not resuming)? */
|
||||||
|
if (p->is_vararg)
|
||||||
|
return 0; /* hooks will start at VARARGPREP instruction */
|
||||||
|
else if (!(ci->callstatus & CIST_HOOKYIELD)) /* not yieded? */
|
||||||
|
luaD_hookcall(L, ci); /* check 'call' hook */
|
||||||
|
}
|
||||||
|
return 1; /* keep 'trap' on */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Traces the execution of a Lua function. Called before the execution
|
** Traces the execution of a Lua function. Called before the execution
|
||||||
** of each opcode, when debug is on. 'L->oldpc' stores the last
|
** of each opcode, when debug is on. 'L->oldpc' stores the last
|
||||||
|
|
1
ldebug.h
1
ldebug.h
|
@ -58,6 +58,7 @@ LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg,
|
||||||
TString *src, int line);
|
TString *src, int line);
|
||||||
LUAI_FUNC l_noret luaG_errormsg (lua_State *L);
|
LUAI_FUNC l_noret luaG_errormsg (lua_State *L);
|
||||||
LUAI_FUNC int luaG_traceexec (lua_State *L, const Instruction *pc);
|
LUAI_FUNC int luaG_traceexec (lua_State *L, const Instruction *pc);
|
||||||
|
LUAI_FUNC int luaG_tracecall (lua_State *L);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
2
lstate.h
2
lstate.h
|
@ -181,7 +181,7 @@ struct CallInfo {
|
||||||
union {
|
union {
|
||||||
struct { /* only for Lua functions */
|
struct { /* only for Lua functions */
|
||||||
const Instruction *savedpc;
|
const Instruction *savedpc;
|
||||||
volatile l_signalT trap;
|
volatile l_signalT trap; /* function is tracing lines/counts */
|
||||||
int nextraargs; /* # of extra arguments in vararg functions */
|
int nextraargs; /* # of extra arguments in vararg functions */
|
||||||
} l;
|
} l;
|
||||||
struct { /* only for C functions */
|
struct { /* only for C functions */
|
||||||
|
|
13
lvm.c
13
lvm.c
|
@ -1157,18 +1157,11 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
startfunc:
|
startfunc:
|
||||||
trap = L->hookmask;
|
trap = L->hookmask;
|
||||||
returning: /* trap already set */
|
returning: /* trap already set */
|
||||||
cl = clLvalue(s2v(ci->func.p));
|
cl = ci_func(ci);
|
||||||
k = cl->p->k;
|
k = cl->p->k;
|
||||||
pc = ci->u.l.savedpc;
|
pc = ci->u.l.savedpc;
|
||||||
if (l_unlikely(trap)) {
|
if (l_unlikely(trap))
|
||||||
if (pc == cl->p->code) { /* first instruction (not resuming)? */
|
trap = luaG_tracecall(L);
|
||||||
if (cl->p->is_vararg)
|
|
||||||
trap = 0; /* hooks will start after VARARGPREP instruction */
|
|
||||||
else /* check 'call' hook */
|
|
||||||
luaD_hookcall(L, ci);
|
|
||||||
}
|
|
||||||
ci->u.l.trap = 1; /* assume trap is on, for now */
|
|
||||||
}
|
|
||||||
base = ci->func.p + 1;
|
base = ci->func.p + 1;
|
||||||
/* main loop of interpreter */
|
/* main loop of interpreter */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
Loading…
Reference in New Issue