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-a62fca1ebb0798676a11c5bda2406e36de654b6e.tar.gz
lua-a62fca1ebb0798676a11c5bda2406e36de654b6e.tar.bz2
lua-a62fca1ebb0798676a11c5bda2406e36de654b6e.zip
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:
974+ g->estimate -= GCFINALIZECOST; 974+ g->estimate -= GCFINALIZECOST;
975]] 975]]
976} 976}
977
978
979But{
980
981what = [[debug hooks may get wrong when mixed with coroutines]],
982
983report = [[by Ivko Stanilov, 03/06/2006]],
984
985example = [[
986co = coroutine.create(function (a,b)
987 coroutine.yield(a, b)
988 return b, "end"
989end)
990
991debug.sethook(co, function() end, "lcr")
992coroutine.resume(co, 100, 2000)
993coroutine.resume(co, 100, 2000)
994]],
995
996patch = [[
997* ldo.c:
998@@ -389,6 +389,7 @@
999 return;
1000 }
1001 else { /* resuming from previous yield */
1002+ L->status = 0;
1003 if (!f_isLua(ci)) { /* `common' yield? */
1004 /* finish interrupted execution of `OP_CALL' */
1005 lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL ||
1006@@ -399,7 +400,6 @@
1007 else /* yielded inside a hook: just continue its execution */
1008 L->base = L->ci->base;
1009 }
1010- L->status = 0;
1011 luaV_execute(L, cast_int(L->ci - L->base_ci));
1012 }
1013]],
1014
1015}
diff --git a/ldo.c b/ldo.c
index e8346009..d7a587e9 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 2.36 2005/10/23 17:52:42 roberto Exp roberto $ 2** $Id: ldo.c,v 2.37 2005/12/22 16:19:56 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -383,12 +383,14 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
383static void resume (lua_State *L, void *ud) { 383static void resume (lua_State *L, void *ud) {
384 StkId firstArg = cast(StkId, ud); 384 StkId firstArg = cast(StkId, ud);
385 CallInfo *ci = L->ci; 385 CallInfo *ci = L->ci;
386 if (L->status != LUA_YIELD) { /* start coroutine */ 386 if (L->status == 0) { /* start coroutine? */
387 lua_assert(ci == L->base_ci && firstArg > L->base); 387 lua_assert(ci == L->base_ci && firstArg > L->base);
388 if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA) 388 if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA)
389 return; 389 return;
390 } 390 }
391 else { /* resuming from previous yield */ 391 else { /* resuming from previous yield */
392 lua_assert(L->status == LUA_YIELD);
393 L->status = 0;
392 if (!f_isLua(ci)) { /* `common' yield? */ 394 if (!f_isLua(ci)) { /* `common' yield? */
393 /* finish interrupted execution of `OP_CALL' */ 395 /* finish interrupted execution of `OP_CALL' */
394 lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL || 396 lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL ||
@@ -399,7 +401,6 @@ static void resume (lua_State *L, void *ud) {
399 else /* yielded inside a hook: just continue its execution */ 401 else /* yielded inside a hook: just continue its execution */
400 L->base = L->ci->base; 402 L->base = L->ci->base;
401 } 403 }
402 L->status = 0;
403 luaV_execute(L, cast_int(L->ci - L->base_ci)); 404 luaV_execute(L, cast_int(L->ci - L->base_ci));
404} 405}
405 406