lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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.