aboutsummaryrefslogtreecommitdiff
path: root/ldebug.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-01-11 13:44:16 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-01-11 13:44:16 -0300
commite288c5a91883793d14ed9e9d93464f6ee0b08915 (patch)
treef563f9b4d218c9e35ff3e56eda068cfddb039651 /ldebug.c
parent5853c37a83ec66ccb45094f9aeac23dfdbcde671 (diff)
downloadlua-e288c5a91883793d14ed9e9d93464f6ee0b08915.tar.gz
lua-e288c5a91883793d14ed9e9d93464f6ee0b08915.tar.bz2
lua-e288c5a91883793d14ed9e9d93464f6ee0b08915.zip
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.
Diffstat (limited to 'ldebug.c')
-rw-r--r--ldebug.c5
1 files changed, 2 insertions, 3 deletions
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) {
925 } 925 }
926 pc++; /* reference is always next instruction */ 926 pc++; /* reference is always next instruction */
927 ci->u.l.savedpc = pc; /* save 'pc' */ 927 ci->u.l.savedpc = pc; /* save 'pc' */
928 counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT)); 928 counthook = (mask & LUA_MASKCOUNT) && (--L->hookcount == 0);
929 if (counthook) 929 if (counthook)
930 resethookcount(L); /* reset count */ 930 resethookcount(L); /* reset count */
931 else if (!(mask & LUA_MASKLINE)) 931 else if (!(mask & LUA_MASKLINE))
932 return 1; /* no line hook and count != 0; nothing to be done now */ 932 return 1; /* no line hook and count != 0; nothing to be done now */
933 if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */ 933 if (ci->callstatus & CIST_HOOKYIELD) { /* hook yielded last time? */
934 ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ 934 ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */
935 return 1; /* do not call hook again (VM yielded, so it did not move) */ 935 return 1; /* do not call hook again (VM yielded, so it did not move) */
936 } 936 }
@@ -952,7 +952,6 @@ int luaG_traceexec (lua_State *L, const Instruction *pc) {
952 if (L->status == LUA_YIELD) { /* did hook yield? */ 952 if (L->status == LUA_YIELD) { /* did hook yield? */
953 if (counthook) 953 if (counthook)
954 L->hookcount = 1; /* undo decrement to zero */ 954 L->hookcount = 1; /* undo decrement to zero */
955 ci->u.l.savedpc--; /* undo increment (resume will increment it again) */
956 ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ 955 ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */
957 luaD_throw(L, LUA_YIELD); 956 luaD_throw(L, LUA_YIELD);
958 } 957 }