diff options
| -rw-r--r-- | lcorolib.c | 4 | ||||
| -rw-r--r-- | lstate.c | 3 | ||||
| -rw-r--r-- | ltests.c | 2 | ||||
| -rw-r--r-- | lua.h | 2 | ||||
| -rw-r--r-- | manual/manual.of | 7 | ||||
| -rw-r--r-- | testes/cstack.lua | 26 |
6 files changed, 38 insertions, 6 deletions
| @@ -76,7 +76,7 @@ static int luaB_auxwrap (lua_State *L) { | |||
| 76 | if (l_unlikely(r < 0)) { /* error? */ | 76 | if (l_unlikely(r < 0)) { /* error? */ |
| 77 | int stat = lua_status(co); | 77 | int stat = lua_status(co); |
| 78 | if (stat != LUA_OK && stat != LUA_YIELD) { /* error in the coroutine? */ | 78 | if (stat != LUA_OK && stat != LUA_YIELD) { /* error in the coroutine? */ |
| 79 | stat = lua_resetthread(co); /* close its tbc variables */ | 79 | stat = lua_resetthread(co, L); /* close its tbc variables */ |
| 80 | lua_assert(stat != LUA_OK); | 80 | lua_assert(stat != LUA_OK); |
| 81 | lua_xmove(co, L, 1); /* move error message to the caller */ | 81 | lua_xmove(co, L, 1); /* move error message to the caller */ |
| 82 | } | 82 | } |
| @@ -172,7 +172,7 @@ static int luaB_close (lua_State *L) { | |||
| 172 | int status = auxstatus(L, co); | 172 | int status = auxstatus(L, co); |
| 173 | switch (status) { | 173 | switch (status) { |
| 174 | case COS_DEAD: case COS_YIELD: { | 174 | case COS_DEAD: case COS_YIELD: { |
| 175 | status = lua_resetthread(co); | 175 | status = lua_resetthread(co, L); |
| 176 | if (status == LUA_OK) { | 176 | if (status == LUA_OK) { |
| 177 | lua_pushboolean(L, 1); | 177 | lua_pushboolean(L, 1); |
| 178 | return 1; | 178 | return 1; |
| @@ -343,9 +343,10 @@ int luaE_resetthread (lua_State *L, int status) { | |||
| 343 | } | 343 | } |
| 344 | 344 | ||
| 345 | 345 | ||
| 346 | LUA_API int lua_resetthread (lua_State *L) { | 346 | LUA_API int lua_resetthread (lua_State *L, lua_State *from) { |
| 347 | int status; | 347 | int status; |
| 348 | lua_lock(L); | 348 | lua_lock(L); |
| 349 | L->nCcalls = (from) ? getCcalls(from) : 0; | ||
| 349 | status = luaE_resetthread(L, L->status); | 350 | status = luaE_resetthread(L, L->status); |
| 350 | lua_unlock(L); | 351 | lua_unlock(L); |
| 351 | return status; | 352 | return status; |
| @@ -1533,7 +1533,7 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) { | |||
| 1533 | lua_newthread(L1); | 1533 | lua_newthread(L1); |
| 1534 | } | 1534 | } |
| 1535 | else if EQ("resetthread") { | 1535 | else if EQ("resetthread") { |
| 1536 | lua_pushinteger(L1, lua_resetthread(L1)); | 1536 | lua_pushinteger(L1, lua_resetthread(L1, L)); |
| 1537 | } | 1537 | } |
| 1538 | else if EQ("newuserdata") { | 1538 | else if EQ("newuserdata") { |
| 1539 | lua_newuserdata(L1, getnum); | 1539 | lua_newuserdata(L1, getnum); |
| @@ -153,7 +153,7 @@ extern const char lua_ident[]; | |||
| 153 | LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); | 153 | LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); |
| 154 | LUA_API void (lua_close) (lua_State *L); | 154 | LUA_API void (lua_close) (lua_State *L); |
| 155 | LUA_API lua_State *(lua_newthread) (lua_State *L); | 155 | LUA_API lua_State *(lua_newthread) (lua_State *L); |
| 156 | LUA_API int (lua_resetthread) (lua_State *L); | 156 | LUA_API int (lua_resetthread) (lua_State *L, lua_State *from); |
| 157 | 157 | ||
| 158 | LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); | 158 | LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); |
| 159 | 159 | ||
diff --git a/manual/manual.of b/manual/manual.of index 10c16bd1..6d19e251 100644 --- a/manual/manual.of +++ b/manual/manual.of | |||
| @@ -4160,7 +4160,7 @@ and then pops the top element. | |||
| 4160 | 4160 | ||
| 4161 | } | 4161 | } |
| 4162 | 4162 | ||
| 4163 | @APIEntry{int lua_resetthread (lua_State *L);| | 4163 | @APIEntry{int lua_resetthread (lua_State *L, lua_State *from);| |
| 4164 | @apii{0,?,-} | 4164 | @apii{0,?,-} |
| 4165 | 4165 | ||
| 4166 | Resets a thread, cleaning its call stack and closing all pending | 4166 | Resets a thread, cleaning its call stack and closing all pending |
| @@ -4173,6 +4173,11 @@ or an error status otherwise. | |||
| 4173 | In case of error, | 4173 | In case of error, |
| 4174 | leaves the error object on the top of the stack. | 4174 | leaves the error object on the top of the stack. |
| 4175 | 4175 | ||
| 4176 | The parameter @id{from} represents the coroutine that is resetting @id{L}. | ||
| 4177 | If there is no such coroutine, | ||
| 4178 | this parameter can be @id{NULL}. | ||
| 4179 | (This parameter was introduced in @N{release 5.4.5}.) | ||
| 4180 | |||
| 4176 | } | 4181 | } |
| 4177 | 4182 | ||
| 4178 | @APIEntry{int lua_resume (lua_State *L, lua_State *from, int nargs, | 4183 | @APIEntry{int lua_resume (lua_State *L, lua_State *from, int nargs, |
diff --git a/testes/cstack.lua b/testes/cstack.lua index ca76c872..97afe9fd 100644 --- a/testes/cstack.lua +++ b/testes/cstack.lua | |||
| @@ -84,6 +84,32 @@ do -- bug in 5.4.0 | |||
| 84 | end | 84 | end |
| 85 | 85 | ||
| 86 | 86 | ||
| 87 | do -- bug since 5.4.0 | ||
| 88 | local count = 0 | ||
| 89 | print("chain of 'coroutine.close'") | ||
| 90 | -- create N coroutines forming a list so that each one, when closed, | ||
| 91 | -- closes the previous one. (With a large enough N, previous Lua | ||
| 92 | -- versions crash in this test.) | ||
| 93 | local coro = false | ||
| 94 | for i = 1, 1000 do | ||
| 95 | local previous = coro | ||
| 96 | coro = coroutine.create(function() | ||
| 97 | local cc <close> = setmetatable({}, {__close=function() | ||
| 98 | count = count + 1 | ||
| 99 | if previous then | ||
| 100 | assert(coroutine.close(previous)) | ||
| 101 | end | ||
| 102 | end}) | ||
| 103 | coroutine.yield() -- leaves 'cc' pending to be closed | ||
| 104 | end) | ||
| 105 | assert(coroutine.resume(coro)) -- start it and run until it yields | ||
| 106 | end | ||
| 107 | local st, msg = coroutine.close(coro) | ||
| 108 | assert(not st and string.find(msg, "C stack overflow")) | ||
| 109 | print("final count: ", count) | ||
| 110 | end | ||
| 111 | |||
| 112 | |||
| 87 | do | 113 | do |
| 88 | print("nesting of resuming yielded coroutines") | 114 | print("nesting of resuming yielded coroutines") |
| 89 | local count = 0 | 115 | local count = 0 |
