No more to-be-closed functions

To-be-closed variables must contain objects with '__toclose'
metamethods (or nil). Functions were removed for several reasons:

* Functions interact badly with sandboxes. If a sandbox raises
an error to interrupt a script, a to-be-closed function still
can hijack control and continue running arbitrary sandboxed code.

* Functions interact badly with coroutines. If a coroutine yields
and is never resumed again, its to-be-closed functions will never
run. To-be-closed objects, on the other hand, will still be closed,
provided they have appropriate finalizers.

* If you really need a function, it is easy to create a dummy
object to run that function in its '__toclose' metamethod.

This comit also adds closing of variables in case of panic.
This commit is contained in:
Roberto Ierusalimschy
2019-01-04 13:09:47 -02:00
parent c6f7181e91
commit 4ace93ca65
8 changed files with 97 additions and 68 deletions

View File

@@ -142,8 +142,15 @@ do
-- to-be-closed variables in coroutines
local X
local function func2close (f)
return setmetatable({}, {__close = f})
end
co = coroutine.create(function ()
local *toclose x = function (err) assert(err == nil); X = false end
local *toclose x = func2close(function (self, err)
assert(err == nil); X = false
end)
X = true
coroutine.yield()
end)
@@ -154,7 +161,9 @@ do
-- error killing a coroutine
co = coroutine.create(function()
local *toclose x = function (err) assert(err == nil); error(111) end
local *toclose x = func2close(function (self, err)
assert(err == nil); error(111)
end)
coroutine.yield()
end)
coroutine.resume(co)