aboutsummaryrefslogtreecommitdiff
path: root/testes
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2021-02-12 13:36:30 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2021-02-12 13:36:30 -0300
commitbc970005ce2e258e29a5c315ea4e49f76a66586e (patch)
tree5575ca66aeddad2036df74f38fa2bed217c2801e /testes
parentf79ccdca9bbe9d486d91a44a4464b99ce38de0e2 (diff)
downloadlua-bc970005ce2e258e29a5c315ea4e49f76a66586e.tar.gz
lua-bc970005ce2e258e29a5c315ea4e49f76a66586e.tar.bz2
lua-bc970005ce2e258e29a5c315ea4e49f76a66586e.zip
'__close' methods can yield in the return of a C function
When, inside a coroutine, a C function with to-be-closed slots return, the corresponding metamethods can yield. ('__close' metamethods called through 'lua_closeslot' still cannot yield, as there is no continuation to go when resuming.)
Diffstat (limited to 'testes')
-rw-r--r--testes/locals.lua76
1 files changed, 75 insertions, 1 deletions
diff --git a/testes/locals.lua b/testes/locals.lua
index 446ec13a..a93839db 100644
--- a/testes/locals.lua
+++ b/testes/locals.lua
@@ -707,7 +707,6 @@ if rawget(_G, "T") then
707 -- results are correct 707 -- results are correct
708 checktable(t, {10, 20}) 708 checktable(t, {10, 20})
709 end 709 end
710
711end 710end
712 711
713 712
@@ -930,6 +929,81 @@ assert(co == nil) -- eventually it will be collected
930collectgarbage() 929collectgarbage()
931 930
932 931
932if rawget(_G, "T") then
933 print("to-be-closed variables x coroutines in C")
934 do
935 local token = 0
936 local count = 0
937 local f = T.makeCfunc[[
938 toclose 1
939 toclose 2
940 return .
941 ]]
942
943 local obj = func2close(function (_, msg)
944 count = count + 1
945 token = coroutine.yield(count, token)
946 end)
947
948 local co = coroutine.wrap(f)
949 local ct, res = co(obj, obj, 10, 20, 30, 3) -- will return 10, 20, 30
950 -- initial token value, after closing 2nd obj
951 assert(ct == 1 and res == 0)
952 -- run until yield when closing 1st obj
953 ct, res = co(100)
954 assert(ct == 2 and res == 100)
955 res = {co(200)} -- run until end
956 assert(res[1] == 10 and res[2] == 20 and res[3] == 30 and res[4] == nil)
957 assert(token == 200)
958 end
959
960 do
961 local f = T.makeCfunc[[
962 toclose 1
963 return .
964 ]]
965
966 local obj = func2close(function ()
967 local temp
968 local x <close> = func2close(function ()
969 coroutine.yield(temp)
970 return 1,2,3 -- to be ignored
971 end)
972 temp = coroutine.yield("closing obj")
973 return 1,2,3 -- to be ignored
974 end)
975
976 local co = coroutine.wrap(f)
977 local res = co(obj, 10, 30, 1) -- will return only 30
978 assert(res == "closing obj")
979 res = co("closing x")
980 assert(res == "closing x")
981 res = {co()}
982 assert(res[1] == 30 and res[2] == nil)
983 end
984
985 do
986 -- still cannot yield inside 'closeslot'
987 local f = T.makeCfunc[[
988 toclose 1
989 closeslot 1
990 ]]
991 local obj = func2close(coroutine.yield)
992 local co = coroutine.create(f)
993 local st, msg = coroutine.resume(co, obj)
994 assert(not st and string.find(msg, "attempt to yield across"))
995
996 -- nor outside a coroutine
997 local f = T.makeCfunc[[
998 toclose 1
999 ]]
1000 local st, msg = pcall(f, obj)
1001 assert(not st and string.find(msg, "attempt to yield from outside"))
1002 end
1003end
1004
1005
1006
933-- to-be-closed variables in generic for loops 1007-- to-be-closed variables in generic for loops
934do 1008do
935 local numopen = 0 1009 local numopen = 0