[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Yielding in Close Call through Vararg Return Changes Number of Returns
- From: Xmilia Hermit <xmilia.hermit@...>
- Date: Wed, 7 Apr 2021 21:00:44 +0200
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