[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: lua 5.3.2 introduced a bug related to coroutines
- From: William Ahern <william@...>
- Date: Thu, 17 Mar 2016 18:07:51 -0700
On Fri, Mar 18, 2016 at 02:07:11AM +0300, Nagaev Boris wrote:
> $ cat bug.lua
> local function yieldFirst(it)
> return coroutine.wrap(function()
> coroutine.yield(it())
> end)
> end
>
> local text = "1 2 3"
> local it = text:gmatch("(%d+)")
> local head = yieldFirst(it)
> local one = head()
> print(one)
> assert(one == '1')
>
> $ ./lua-5.3.1/src/lua bug.lua
> 1
> $ ./lua-5.3.2/src/lua bug.lua
> function: 0x243f820
> ./lua-5.3.2/src/lua: bug.lua:12: assertion failed!
> stack traceback:
> [C]: in function 'assert'
> bug.lua:12: in main chunk
> [C]: in ?
>
My first guess is that lstrlib.c:gmatch is storing the lua_State object (see
prepstate) used when creating the closure. When the closure is invoked, it
uses this original lua_State instead of the current lua_State invoking the
closure. But the original lua_State is busy resuming the new lua_State.
The immediate solution might be to add
gm->ms.L = L
to strlib.c:gmatch_aux. I haven't tested it. It might result in wrong error
messages? Maybe not. I don't know why lua_State is being stored in
MatchState except to reduce the number of arguments needed to invoke all the
other routines in strlib.c.