lua-users home
lua-l archive

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


Hi,

it seems that yielding in a close call when the variable is closed by a vararg return can mess up the number of arguments returned since after the yield the OP_RETURN is executed again, however, it changed L->top to ci->top before the close call and so after the yield in the second execution of OP_RETURN n = cast_int(L->top - ra); will result in a different n. The following script shows this problem (compare the output for BUG = true vs false):

local BUG = true

local function test()
    local x <close> = setmetatable({}, {
        __close = function()
            if BUG then coroutine.yield() end
        end
    })
    if not BUG then coroutine.yield() end
    return print("Return")
end

local c = coroutine.wrap(test)
c()
print(c())

The following lines of code seem to be the cause:
https://github.com/lua/lua/blob/eadd8c7178c79c814ecca9652973a9b9dd4cc71b/lvm.c#L851 (Repeat OP_RETURN instruction after yield) https://github.com/lua/lua/blob/eadd8c7178c79c814ecca9652973a9b9dd4cc71b/lvm.c#L1674 (Change top before yield but not reset) https://github.com/lua/lua/blob/eadd8c7178c79c814ecca9652973a9b9dd4cc71b/lvm.c#L1670 (Wrong calculation of n after yield)


Regards,
Xmilia