diff options
-rw-r--r-- | ldebug.c | 5 | ||||
-rw-r--r-- | ldo.c | 4 | ||||
-rw-r--r-- | testes/coroutine.lua | 8 |
3 files changed, 11 insertions, 6 deletions
@@ -925,12 +925,12 @@ int luaG_traceexec (lua_State *L, const Instruction *pc) { | |||
925 | } | 925 | } |
926 | pc++; /* reference is always next instruction */ | 926 | pc++; /* reference is always next instruction */ |
927 | ci->u.l.savedpc = pc; /* save 'pc' */ | 927 | ci->u.l.savedpc = pc; /* save 'pc' */ |
928 | counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT)); | 928 | counthook = (mask & LUA_MASKCOUNT) && (--L->hookcount == 0); |
929 | if (counthook) | 929 | if (counthook) |
930 | resethookcount(L); /* reset count */ | 930 | resethookcount(L); /* reset count */ |
931 | else if (!(mask & LUA_MASKLINE)) | 931 | else if (!(mask & LUA_MASKLINE)) |
932 | return 1; /* no line hook and count != 0; nothing to be done now */ | 932 | return 1; /* no line hook and count != 0; nothing to be done now */ |
933 | if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */ | 933 | if (ci->callstatus & CIST_HOOKYIELD) { /* hook yielded last time? */ |
934 | ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ | 934 | ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ |
935 | return 1; /* do not call hook again (VM yielded, so it did not move) */ | 935 | return 1; /* do not call hook again (VM yielded, so it did not move) */ |
936 | } | 936 | } |
@@ -952,7 +952,6 @@ int luaG_traceexec (lua_State *L, const Instruction *pc) { | |||
952 | if (L->status == LUA_YIELD) { /* did hook yield? */ | 952 | if (L->status == LUA_YIELD) { /* did hook yield? */ |
953 | if (counthook) | 953 | if (counthook) |
954 | L->hookcount = 1; /* undo decrement to zero */ | 954 | L->hookcount = 1; /* undo decrement to zero */ |
955 | ci->u.l.savedpc--; /* undo increment (resume will increment it again) */ | ||
956 | ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ | 955 | ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ |
957 | luaD_throw(L, LUA_YIELD); | 956 | luaD_throw(L, LUA_YIELD); |
958 | } | 957 | } |
@@ -792,6 +792,10 @@ static void resume (lua_State *L, void *ud) { | |||
792 | lua_assert(L->status == LUA_YIELD); | 792 | lua_assert(L->status == LUA_YIELD); |
793 | L->status = LUA_OK; /* mark that it is running (again) */ | 793 | L->status = LUA_OK; /* mark that it is running (again) */ |
794 | if (isLua(ci)) { /* yielded inside a hook? */ | 794 | if (isLua(ci)) { /* yielded inside a hook? */ |
795 | /* undo increment made by 'luaG_traceexec': instruction was not | ||
796 | executed yet */ | ||
797 | lua_assert(ci->callstatus & CIST_HOOKYIELD); | ||
798 | ci->u.l.savedpc--; | ||
795 | L->top.p = firstArg; /* discard arguments */ | 799 | L->top.p = firstArg; /* discard arguments */ |
796 | luaV_execute(L, ci); /* just continue running Lua code */ | 800 | luaV_execute(L, ci); /* just continue running Lua code */ |
797 | } | 801 | } |
diff --git a/testes/coroutine.lua b/testes/coroutine.lua index de7e46fb..e566c86e 100644 --- a/testes/coroutine.lua +++ b/testes/coroutine.lua | |||
@@ -610,18 +610,20 @@ else | |||
610 | -- (bug in 5.2/5.3) | 610 | -- (bug in 5.2/5.3) |
611 | c = coroutine.create(function (a, ...) | 611 | c = coroutine.create(function (a, ...) |
612 | T.sethook("yield 0", "l") -- will yield on next two lines | 612 | T.sethook("yield 0", "l") -- will yield on next two lines |
613 | assert(a == 10) | 613 | local b = a |
614 | return ... | 614 | return ... |
615 | end) | 615 | end) |
616 | 616 | ||
617 | assert(coroutine.resume(c, 1, 2, 3)) -- start coroutine | 617 | assert(coroutine.resume(c, 1, 2, 3)) -- start coroutine |
618 | local n,v = debug.getlocal(c, 0, 1) -- check its local | 618 | local n,v = debug.getlocal(c, 0, 1) -- check its local |
619 | assert(n == "a" and v == 1) | 619 | assert(n == "a" and v == 1 and debug.getlocal(c, 0, 2) ~= "b") |
620 | assert(debug.setlocal(c, 0, 1, 10)) -- test 'setlocal' | 620 | assert(debug.setlocal(c, 0, 1, 10)) -- test 'setlocal' |
621 | local t = debug.getinfo(c, 0) -- test 'getinfo' | 621 | local t = debug.getinfo(c, 0) -- test 'getinfo' |
622 | assert(t.currentline == t.linedefined + 1) | 622 | assert(t.currentline == t.linedefined + 2) |
623 | assert(not debug.getinfo(c, 1)) -- no other level | 623 | assert(not debug.getinfo(c, 1)) -- no other level |
624 | assert(coroutine.resume(c)) -- run next line | 624 | assert(coroutine.resume(c)) -- run next line |
625 | local n,v = debug.getlocal(c, 0, 2) -- check next local | ||
626 | assert(n == "b" and v == 10) | ||
625 | v = {coroutine.resume(c)} -- finish coroutine | 627 | v = {coroutine.resume(c)} -- finish coroutine |
626 | assert(v[1] == true and v[2] == 2 and v[3] == 3 and v[4] == undef) | 628 | assert(v[1] == true and v[2] == 2 and v[3] == 3 and v[4] == undef) |
627 | assert(not coroutine.resume(c)) | 629 | assert(not coroutine.resume(c)) |