diff options
-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 | ||