summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2006-06-05 16:36:45 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2006-06-05 16:36:45 -0300
commita62fca1ebb0798676a11c5bda2406e36de654b6e (patch)
treec0825f2fbbb9a58b5ff204f976bbe36756d15fff
parent2b5c1f99e52fd725b3c3c58d80596dbb4a342da2 (diff)
downloadlua-github-a62fca1ebb0798676a11c5bda2406e36de654b6e.tar.gz
BUG: debug hooks may get wrong when mixed with coroutines
-rw-r--r--bugs39
-rw-r--r--ldo.c7
2 files changed, 43 insertions, 3 deletions
diff --git a/bugs b/bugs
index 878117b1..a9f53823 100644
--- a/bugs
+++ b/bugs
@@ -974,3 +974,42 @@ lgc.c:
+ g->estimate -= GCFINALIZECOST;
]]
}
+
+
+But{
+
+what = [[debug hooks may get wrong when mixed with coroutines]],
+
+report = [[by Ivko Stanilov, 03/06/2006]],
+
+example = [[
+co = coroutine.create(function (a,b)
+ coroutine.yield(a, b)
+ return b, "end"
+end)
+
+debug.sethook(co, function() end, "lcr")
+coroutine.resume(co, 100, 2000)
+coroutine.resume(co, 100, 2000)
+]],
+
+patch = [[
+* ldo.c:
+@@ -389,6 +389,7 @@
+ return;
+ }
+ else { /* resuming from previous yield */
++ L->status = 0;
+ if (!f_isLua(ci)) { /* `common' yield? */
+ /* finish interrupted execution of `OP_CALL' */
+ lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL ||
+@@ -399,7 +400,6 @@
+ else /* yielded inside a hook: just continue its execution */
+ L->base = L->ci->base;
+ }
+- L->status = 0;
+ luaV_execute(L, cast_int(L->ci - L->base_ci));
+ }
+]],
+
+}
diff --git a/ldo.c b/ldo.c
index e8346009..d7a587e9 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldo.c,v 2.36 2005/10/23 17:52:42 roberto Exp roberto $
+** $Id: ldo.c,v 2.37 2005/12/22 16:19:56 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -383,12 +383,14 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
static void resume (lua_State *L, void *ud) {
StkId firstArg = cast(StkId, ud);
CallInfo *ci = L->ci;
- if (L->status != LUA_YIELD) { /* start coroutine */
+ if (L->status == 0) { /* start coroutine? */
lua_assert(ci == L->base_ci && firstArg > L->base);
if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA)
return;
}
else { /* resuming from previous yield */
+ lua_assert(L->status == LUA_YIELD);
+ L->status = 0;
if (!f_isLua(ci)) { /* `common' yield? */
/* finish interrupted execution of `OP_CALL' */
lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL ||
@@ -399,7 +401,6 @@ static void resume (lua_State *L, void *ud) {
else /* yielded inside a hook: just continue its execution */
L->base = L->ci->base;
}
- L->status = 0;
luaV_execute(L, cast_int(L->ci - L->base_ci));
}