From 4ace93ca6502dd1da38d5c06fa099d229e791ba8 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Fri, 4 Jan 2019 13:09:47 -0200 Subject: 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. --- manual/manual.of | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) (limited to 'manual') diff --git a/manual/manual.of b/manual/manual.of index d64f0f1a..b9ab1ebe 100644 --- a/manual/manual.of +++ b/manual/manual.of @@ -1536,33 +1536,29 @@ goes out of scope, including normal block termination, exiting its block by @Rw{break}/@Rw{goto}/@Rw{return}, or exiting by an error. -To \emph{close} a value has the following meaning here: -If the value of the variable when it goes out of scope is a function, -that function is called; -otherwise, if the value has a @idx{__close} metamethod, -that metamethod is called; -otherwise, if the value is @nil, nothing is done; -otherwise, an error is raised. -In the function case, -if the scope is being closed by an error, -the error object is passed as an argument to the function; -if there is no error, the function gets @nil. -In the metamethod case, -the value itself always is passed as an argument to the metamethod. +Here, to \emph{close} a value means +to call its @idx{__close} metamethod. +If the value is @nil, it is ignored; +otherwise, +if it does not have a @idx{__close} metamethod, +an error is raised. +When calling the metamethod, +the value itself is passed as the first argument +and the error object (if any) is passed as a second argument; +if there was no error, the second argument is @nil. If several to-be-closed variables go out of scope at the same event, they are closed in the reverse order that they were declared. -If there is any error while running a closing function, +If there is any error while running a closing method, that error is handled like an error in the regular code where the variable was defined; in particular, -the other pending closing functions will still be called. +the other pending closing methods will still be called. If a coroutine yields inside a block and is never resumed again, the variables visible at that block will never go out of scope, and therefore they will not be closed. -Similarly, if a script is interrupted by an unprotected error, -its to-be-closed variables will not be closed. +(You should use finalizers to handle this case.) } @@ -3002,7 +2998,7 @@ and therefore never returns } @APIEntry{int lua_gc (lua_State *L, int what, int data);| -@apii{0,0,v} +@apii{0,0,-} Controls the garbage collector. @@ -3056,8 +3052,6 @@ returns a boolean that tells whether the collector is running For more details about these options, see @Lid{collectgarbage}. -This function may raise errors when calling finalizers. - } @APIEntry{lua_Alloc lua_getallocf (lua_State *L, void **ud);| -- cgit v1.2.3-55-g6feb