summaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2012-06-08 12:14:04 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2012-06-08 12:14:04 -0300
commitcc2a60ecb7e4c57ed31e5c5c3f49d8dc7447acc5 (patch)
treebd702ddf14ba4e1b57959bf978ec062f03ad861f /lvm.c
parent43bfb60ac8add40a6099b933bc8454c11471c386 (diff)
downloadlua-cc2a60ecb7e4c57ed31e5c5c3f49d8dc7447acc5.tar.gz
lua-cc2a60ecb7e4c57ed31e5c5c3f49d8dc7447acc5.tar.bz2
lua-cc2a60ecb7e4c57ed31e5c5c3f49d8dc7447acc5.zip
bugs in yields inside debug hooks
Diffstat (limited to 'lvm.c')
-rw-r--r--lvm.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/lvm.c b/lvm.c
index cd7642eb..2d27d512 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.150 2012/05/08 13:53:33 roberto Exp roberto $ 2** $Id: lvm.c,v 2.151 2012/05/14 17:50:49 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -60,10 +60,15 @@ int luaV_tostring (lua_State *L, StkId obj) {
60static void traceexec (lua_State *L) { 60static void traceexec (lua_State *L) {
61 CallInfo *ci = L->ci; 61 CallInfo *ci = L->ci;
62 lu_byte mask = L->hookmask; 62 lu_byte mask = L->hookmask;
63 if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) { 63 int counthook = ((mask & LUA_MASKCOUNT) && L->hookcount == 0);
64 resethookcount(L); 64 if (counthook)
65 luaD_hook(L, LUA_HOOKCOUNT, -1); 65 resethookcount(L); /* reset count */
66 if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */
67 ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */
68 return; /* do not call hook again (VM yielded, so it did not move) */
66 } 69 }
70 if (counthook)
71 luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */
67 if (mask & LUA_MASKLINE) { 72 if (mask & LUA_MASKLINE) {
68 Proto *p = ci_func(ci)->p; 73 Proto *p = ci_func(ci)->p;
69 int npc = pcRel(ci->u.l.savedpc, p); 74 int npc = pcRel(ci->u.l.savedpc, p);
@@ -71,11 +76,15 @@ static void traceexec (lua_State *L) {
71 if (npc == 0 || /* call linehook when enter a new function, */ 76 if (npc == 0 || /* call linehook when enter a new function, */
72 ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */ 77 ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */
73 newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */ 78 newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */
74 luaD_hook(L, LUA_HOOKLINE, newline); 79 luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */
75 } 80 }
76 L->oldpc = ci->u.l.savedpc; 81 L->oldpc = ci->u.l.savedpc;
77 if (L->status == LUA_YIELD) { /* did hook yield? */ 82 if (L->status == LUA_YIELD) { /* did hook yield? */
83 if (counthook)
84 L->hookcount = 1; /* undo decrement to zero */
78 ci->u.l.savedpc--; /* undo increment (resume will increment it again) */ 85 ci->u.l.savedpc--; /* undo increment (resume will increment it again) */
86 ci->callstatus |= CIST_HOOKYIELD; /* mark that it yieled */
87 ci->func = L->top - 1; /* protect stack below results */
79 luaD_throw(L, LUA_YIELD); 88 luaD_throw(L, LUA_YIELD);
80 } 89 }
81} 90}