diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2006-06-05 16:36:45 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2006-06-05 16:36:45 -0300 |
commit | a62fca1ebb0798676a11c5bda2406e36de654b6e (patch) | |
tree | c0825f2fbbb9a58b5ff204f976bbe36756d15fff | |
parent | 2b5c1f99e52fd725b3c3c58d80596dbb4a342da2 (diff) | |
download | lua-github-a62fca1ebb0798676a11c5bda2406e36de654b6e.tar.gz |
BUG: debug hooks may get wrong when mixed with coroutines
-rw-r--r-- | bugs | 39 | ||||
-rw-r--r-- | ldo.c | 7 |
2 files changed, 43 insertions, 3 deletions
@@ -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)); + } +]], + +} @@ -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)); } |