aboutsummaryrefslogtreecommitdiff
path: root/testes
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2021-04-16 15:41:44 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2021-04-16 15:41:44 -0300
commit681297187ec45268e872b26753c441586c12bdd8 (patch)
tree90e62c82146470a4c4931801a36f66de0bc92318 /testes
parent5148954eed7550dcac587fce0214b470442efa0d (diff)
downloadlua-681297187ec45268e872b26753c441586c12bdd8.tar.gz
lua-681297187ec45268e872b26753c441586c12bdd8.tar.bz2
lua-681297187ec45268e872b26753c441586c12bdd8.zip
Bug: yielding in '__close' mess up number of returns
Yielding in a __close metamethod called when returning vararg results changes the top and so messes up the number of returned values.
Diffstat (limited to 'testes')
-rw-r--r--testes/locals.lua59
1 files changed, 59 insertions, 0 deletions
diff --git a/testes/locals.lua b/testes/locals.lua
index 6aad5d25..6151f64d 100644
--- a/testes/locals.lua
+++ b/testes/locals.lua
@@ -814,6 +814,65 @@ end
814 814
815 815
816do 816do
817 -- yielding inside closing metamethods while returning
818 -- (bug in 5.4.3)
819
820 local extrares -- result from extra yield (if any)
821
822 local function check (body, extra, ...)
823 local t = table.pack(...) -- expected returns
824 local co = coroutine.wrap(body)
825 if extra then
826 extrares = co() -- runs until first (extra) yield
827 end
828 local res = table.pack(co()) -- runs until yield inside '__close'
829 assert(res.n == 2 and res[2] == nil)
830 local res2 = table.pack(co()) -- runs until end of function
831 assert(res2.n == t.n)
832 for i = 1, #t do
833 if t[i] == "x" then
834 assert(res2[i] == res[1]) -- value that was closed
835 else
836 assert(res2[i] == t[i])
837 end
838 end
839 end
840
841 local function foo ()
842 local x <close> = func2close(coroutine.yield)
843 local extra <close> = func2close(function (self)
844 assert(self == extrares)
845 coroutine.yield(100)
846 end)
847 extrares = extra
848 return table.unpack{10, x, 30}
849 end
850 check(foo, true, 10, "x", 30)
851 assert(extrares == 100)
852
853 local function foo ()
854 local x <close> = func2close(coroutine.yield)
855 return
856 end
857 check(foo, false)
858
859 local function foo ()
860 local x <close> = func2close(coroutine.yield)
861 local y, z = 20, 30
862 return x
863 end
864 check(foo, false, "x")
865
866 local function foo ()
867 local x <close> = func2close(coroutine.yield)
868 local extra <close> = func2close(coroutine.yield)
869 return table.unpack({}, 1, 100) -- 100 nils
870 end
871 check(foo, true, table.unpack({}, 1, 100))
872
873end
874
875do
817 -- yielding inside closing metamethods after an error 876 -- yielding inside closing metamethods after an error
818 877
819 local co = coroutine.wrap(function () 878 local co = coroutine.wrap(function ()