diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2012-06-08 12:14:04 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2012-06-08 12:14:04 -0300 |
commit | cc2a60ecb7e4c57ed31e5c5c3f49d8dc7447acc5 (patch) | |
tree | bd702ddf14ba4e1b57959bf978ec062f03ad861f /lvm.c | |
parent | 43bfb60ac8add40a6099b933bc8454c11471c386 (diff) | |
download | lua-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.c | 19 |
1 files changed, 14 insertions, 5 deletions
@@ -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) { | |||
60 | static void traceexec (lua_State *L) { | 60 | static 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 | } |