[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:12:33 -0700
On Thu, Mar 17, 2016 at 06:07:51PM -0700, William Ahern wrote:
> 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
>
This is probably the correct solution. In Lua 5.2 the initialization of
MatchState happens every time gmatch_aux (the closure) is invoked. It looks
like for 5.3 this was refactored so that MatchState is only initialized
once. But what was forgotten in the process is that lua_State might change
when the closure is invoked.