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-a62fca1ebb0798676a11c5bda2406e36de654b6e.tar.gz lua-a62fca1ebb0798676a11c5bda2406e36de654b6e.tar.bz2 lua-a62fca1ebb0798676a11c5bda2406e36de654b6e.zip | |
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: | |||
| 974 | + g->estimate -= GCFINALIZECOST; | 974 | + g->estimate -= GCFINALIZECOST; |
| 975 | ]] | 975 | ]] |
| 976 | } | 976 | } |
| 977 | |||
| 978 | |||
| 979 | But{ | ||
| 980 | |||
| 981 | what = [[debug hooks may get wrong when mixed with coroutines]], | ||
| 982 | |||
| 983 | report = [[by Ivko Stanilov, 03/06/2006]], | ||
| 984 | |||
| 985 | example = [[ | ||
| 986 | co = coroutine.create(function (a,b) | ||
| 987 | coroutine.yield(a, b) | ||
| 988 | return b, "end" | ||
| 989 | end) | ||
| 990 | |||
| 991 | debug.sethook(co, function() end, "lcr") | ||
| 992 | coroutine.resume(co, 100, 2000) | ||
| 993 | coroutine.resume(co, 100, 2000) | ||
| 994 | ]], | ||
| 995 | |||
| 996 | patch = [[ | ||
| 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 | } | ||
| @@ -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) { | |||
| 383 | static void resume (lua_State *L, void *ud) { | 383 | static 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 | ||
