From e288c5a91883793d14ed9e9d93464f6ee0b08915 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Thu, 11 Jan 2024 13:44:16 -0300 Subject: Bug: Yielding in a hook stops in the wrong instruction Yielding in a hook must decrease the program counter, because it already counted an instruction that, in the end, was not executed. However, that decrement should be done only when about to restart the thread. Otherwise, inspecting the thread with the debug library shows it one instruction behind of where it really is. --- ldebug.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'ldebug.c') diff --git a/ldebug.c b/ldebug.c index b1f16ac9..d6f132ea 100644 --- a/ldebug.c +++ b/ldebug.c @@ -925,12 +925,12 @@ int luaG_traceexec (lua_State *L, const Instruction *pc) { } pc++; /* reference is always next instruction */ ci->u.l.savedpc = pc; /* save 'pc' */ - counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT)); + counthook = (mask & LUA_MASKCOUNT) && (--L->hookcount == 0); if (counthook) resethookcount(L); /* reset count */ else if (!(mask & LUA_MASKLINE)) return 1; /* no line hook and count != 0; nothing to be done now */ - if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */ + if (ci->callstatus & CIST_HOOKYIELD) { /* hook yielded last time? */ ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ return 1; /* do not call hook again (VM yielded, so it did not move) */ } @@ -952,7 +952,6 @@ int luaG_traceexec (lua_State *L, const Instruction *pc) { 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 */ luaD_throw(L, LUA_YIELD); } -- cgit v1.2.3-55-g6feb