From 1b3f507f620d996ffb69da7476a19251acfb89ca Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 25 Jul 2023 16:50:44 -0300 Subject: 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. --- ldebug.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'ldebug.c') diff --git a/ldebug.c b/ldebug.c index 28b1caab..195d02f8 100644 --- a/ldebug.c +++ b/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 ** of each opcode, when debug is on. 'L->oldpc' stores the last -- cgit v1.2.3-55-g6feb