diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2021-01-21 10:27:22 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2021-01-21 10:27:22 -0300 |
commit | 0e9254dfa03d95c3aa2888cf78e9a30bc88d41bc (patch) | |
tree | ca3c956e03f8ecc03eb7ed155c8b6f5e3ebef801 /testes/locals.lua | |
parent | 6ccd24eff58340c00db2877c4558a63c6b859442 (diff) | |
download | lua-github-0e9254dfa03d95c3aa2888cf78e9a30bc88d41bc.tar.gz |
Correct order of return hooks vs. close metamethods
The return hook should be called only after closing variables (which
are still part of the function). C functions were calling the hook
before the metamethods.
Diffstat (limited to 'testes/locals.lua')
-rw-r--r-- | testes/locals.lua | 77 |
1 files changed, 70 insertions, 7 deletions
diff --git a/testes/locals.lua b/testes/locals.lua index 24a95d18..a25b2b9f 100644 --- a/testes/locals.lua +++ b/testes/locals.lua @@ -521,6 +521,14 @@ do -- tbc inside close methods end +local function checktable (t1, t2) + assert(#t1 == #t2) + for i = 1, #t1 do + assert(t1[i] == t2[i]) + end +end + + if rawget(_G, "T") then -- memory error inside closing function @@ -632,6 +640,68 @@ if rawget(_G, "T") then print'+' end + + do + -- '__close' vs. return hooks in C functions + local trace = {} + + local function hook (event) + trace[#trace + 1] = event .. " " .. (debug.getinfo(2).name or "?") + end + + -- create tbc variables to be used by C function + local x = func2close(function (_,msg) + trace[#trace + 1] = "x" + end) + + local y = func2close(function (_,msg) + trace[#trace + 1] = "y" + end) + + debug.sethook(hook, "r") + local t = {T.testC([[ + toclose 2 # x + pushnum 10 + pushint 20 + toclose 3 # y + return 2 + ]], x, y)} + debug.sethook() + + -- hooks ran before return hook from 'testC' + checktable(trace, + {"return sethook", "y", "return ?", "x", "return ?", "return testC"}) + -- results are correct + checktable(t, {10, 20}) + end + +end + + +do -- '__close' vs. return hooks in Lua functions + local trace = {} + + local function hook (event) + trace[#trace + 1] = event .. " " .. debug.getinfo(2).name + end + + local function foo (...) + local x <close> = func2close(function (_,msg) + trace[#trace + 1] = "x" + end) + + local y <close> = func2close(function (_,msg) + debug.sethook(hook, "r") + end) + + return ... + end + + local t = {foo(10,20,30)} + debug.sethook() + checktable(t, {10, 20, 30}) + checktable(trace, + {"return sethook", "return close", "x", "return close", "return foo"}) end @@ -640,13 +710,6 @@ print "to-be-closed variables in coroutines" do -- yielding inside closing metamethods - local function checktable (t1, t2) - assert(#t1 == #t2) - for i = 1, #t1 do - assert(t1[i] == t2[i]) - end - end - local trace = {} local co = coroutine.wrap(function () |