block-scope finalization

classic Classic list List threaded Threaded
86 messages Options
12345
Reply | Threaded
Open this post in threaded view
|

Re: block-scope finalization

Philipp Janda
Am 24.11.2015 um 18:20 schröbte Viacheslav Usov:
> On Tue, Nov 24, 2015 at 5:48 PM, Philipp Janda <[hidden email]> wrote:
>
>> This case should be handled in all libraries.
>
> Sure. The question is, is that really the case?

No, it's definitely not the case :-)

>
>> Adding ref counting wouldn't unbreak the currently broken libraries.
>
> The goal is not to unbreak. It is to keep those broken libs that manage to
> work in the hands of their users, working.
>
>> And adding ref counting might break existing code: a simple
> `lua_replace()` can now run finalizers and thus raise errors and cause
> leaks in the C code.
>
> I do not think I understand this part. Why would ref counting +
> lua_replace() run finalizers?

`lua_replace` overwrites a stack slot. If that stack slot contained the
last reference to a value, that value has to be finalized. The same
applies to `lua_pop`, `lua_remove`, `lua_copy`, `lua_xmove`,
`lua_rawget`, `lua_next`, etc.

>
> Cheers,
> V.
>

Philipp




Reply | Threaded
Open this post in threaded view
|

Re: block-scope finalization

Roberto Ierusalimschy
In reply to this post by Patrick Donnelly
> Open question: should __close be called after or before the "message
> handler" for lua_pcall? I think after makes sense as the handler may
> want to look at the open objects on the stack.

It is not open, this question. When the message handler is called, the
local is still in scope. The call happens when it goes out of scope.

-- Roberto

Reply | Threaded
Open this post in threaded view
|

Re: block-scope finalization

Viacheslav Usov
In reply to this post by Roberto Ierusalimschy
On Tue, Nov 24, 2015 at 6:34 PM, Roberto Ierusalimschy <[hidden email]> wrote:

> I don't think ref couting is a viable option. It has problems with cycles and it is slow.

Cycles: my proposal was ref counting PLUS GC. This takes care of cycles. Circularly referenced objects will not have deterministic finalization.

Slow: I have something to say about the performance of ref counting, but before even going there, what I would really like to understand is whether there are any non-performance arguments against RC + GC in Lua?

Cheers,
V.

Reply | Threaded
Open this post in threaded view
|

Re: block-scope finalization

Viacheslav Usov
In reply to this post by Philipp Janda
On Tue, Nov 24, 2015 at 6:34 PM, Philipp Janda <[hidden email]> wrote:

> `lua_replace` overwrites a stack slot. If that stack slot contained the last reference to a value, that value has to be finalized. The same applies to `lua_pop`, `lua_remove`, `lua_copy`, `lua_xmove`, `lua_rawget`, `lua_next`, etc.

It is not the slots that should have ref counts. Slots stay what they are. It is the objects (userdata and tables) that should have ref counts

Cheers,
V.
Reply | Threaded
Open this post in threaded view
|

Re: block-scope finalization

Roberto Ierusalimschy
In reply to this post by Philipp Janda
> That criteria appears to not be sufficient, e.g. `lua_error` doesn't
> push elements according to the manual, but `luaG_errormsg` uses
> `EXTRA_STACK` space. And some `luaL_` functions might use functions
> that push internally (e.g. `luaL_len` or `luaL_ref`).

Sorry, I thought you were talking about LUA_MINSTACK, because there
is no EXTRA_STACK in the API. EXTRA_STACK is an implementation detail
that should not concern API users. As I said, if the function does
not push something (according to its documentation), it should not
need stack slots. The fact that luaG_errormsg uses EXTRA_STACK is
completely irrelevant here (*). In Lua, we respect the manual. (If the
implementation says otherwise, it is a bug to be fixed.)

(*) Going down to the implementation, EXTRA_STACK serves exactly to
allow those internal pushes even when apparently there are no more
slots available.

-- Roberto

Reply | Threaded
Open this post in threaded view
|

Re: block-scope finalization

Philipp Janda
In reply to this post by Viacheslav Usov
Am 24.11.2015 um 18:51 schröbte Viacheslav Usov:
> On Tue, Nov 24, 2015 at 6:34 PM, Philipp Janda <[hidden email]> wrote:
>
>> `lua_replace` overwrites a stack slot. If that stack slot contained the
> last reference to a value, that value has to be finalized. The same applies
> to `lua_pop`, `lua_remove`, `lua_copy`, `lua_xmove`, `lua_rawget`,
> `lua_next`, etc.
>
> It is not the slots that should have ref counts. Slots stay what they are.
> It is the objects (userdata and tables) that should have ref counts

I'm not sure I can follow. When would you update the reference counts?

>
> Cheers,
> V.
>

Philipp




Reply | Threaded
Open this post in threaded view
|

Re: block-scope finalization

Coda Highland
On Tue, Nov 24, 2015 at 10:48 AM, Philipp Janda <[hidden email]> wrote:

> Am 24.11.2015 um 18:51 schröbte Viacheslav Usov:
>>
>> On Tue, Nov 24, 2015 at 6:34 PM, Philipp Janda <[hidden email]> wrote:
>>
>>> `lua_replace` overwrites a stack slot. If that stack slot contained the
>>
>> last reference to a value, that value has to be finalized. The same
>> applies
>> to `lua_pop`, `lua_remove`, `lua_copy`, `lua_xmove`, `lua_rawget`,
>> `lua_next`, etc.
>>
>> It is not the slots that should have ref counts. Slots stay what they are.
>> It is the objects (userdata and tables) that should have ref counts
>
>
> I'm not sure I can follow. When would you update the reference counts?

When the object is assigned to a stack slot, when it's removed from a
stack slot, when it's assigned to a table field, when it's removed
from a table field, when it's assigned to a table key, when it's used
as a key to store nil into a table, when a table that contains it is
destroyed. The exceptions are weak tables, where being assigned as a
weak key/value does not modify the refcount (but has to track a
backpointer to clean it up).

/s/ Adam

Reply | Threaded
Open this post in threaded view
|

Re: block-scope finalization

Dibyendu Majumdar
In reply to this post by Roberto Ierusalimschy
On 24 November 2015 at 16:52, Roberto Ierusalimschy
<[hidden email]> wrote:

> What is wrong with the following proposal?
>
>   local <some mark to be invented> name = exp
>
> Unlike a regular 'local' declaration, this one must define only one
> variable and it must be initialized. (Both restrictions could be easily
> removed; they are more about programming style.)
>
> When the local 'name' goes out of scope, then:
>
> 1 - if its value is a function, that function is called (no parameters)
> 2 - if its value is a table/userdata, its __close (or some other new
> name) metamethod, if present, is called.
>
> Otherwise, 'name' is like any other local variable.
>

I haven't followed the whole conversation so apologies if I have got
this wrong. If the aim is to provide a 'finally' type feature then an
important aspect is that the finally code must execute even when
exceptions occur. In the above proposal how will Lua ensure that the
function will always be called when the block exits even if there was
an exception which jumped down the stack?

Regards
Dibyendu

Reply | Threaded
Open this post in threaded view
|

Re: block-scope finalization

Coda Highland
On Tue, Nov 24, 2015 at 12:42 PM, Dibyendu Majumdar
<[hidden email]> wrote:

> On 24 November 2015 at 16:52, Roberto Ierusalimschy
> <[hidden email]> wrote:
>> What is wrong with the following proposal?
>>
>>   local <some mark to be invented> name = exp
>>
>> Unlike a regular 'local' declaration, this one must define only one
>> variable and it must be initialized. (Both restrictions could be easily
>> removed; they are more about programming style.)
>>
>> When the local 'name' goes out of scope, then:
>>
>> 1 - if its value is a function, that function is called (no parameters)
>> 2 - if its value is a table/userdata, its __close (or some other new
>> name) metamethod, if present, is called.
>>
>> Otherwise, 'name' is like any other local variable.
>>
>
> I haven't followed the whole conversation so apologies if I have got
> this wrong. If the aim is to provide a 'finally' type feature then an
> important aspect is that the finally code must execute even when
> exceptions occur. In the above proposal how will Lua ensure that the
> function will always be called when the block exits even if there was
> an exception which jumped down the stack?
>
> Regards
> Dibyendu
>

Because "going out of scope" is really just another name for "is
popped off the stack." If an error unwinds the stack, then it would
have to check for the presence of these marked slots on the way down
instead of just changing the stack top index.

/s/ Adam

Reply | Threaded
Open this post in threaded view
|

Re: block-scope finalization

Philipp Janda
In reply to this post by Coda Highland
Am 24.11.2015 um 21:12 schröbte Coda Highland:

> On Tue, Nov 24, 2015 at 10:48 AM, Philipp Janda <[hidden email]> wrote:
>> Am 24.11.2015 um 18:51 schröbte Viacheslav Usov:
>>>
>>> On Tue, Nov 24, 2015 at 6:34 PM, Philipp Janda <[hidden email]> wrote:
>>>
>>>> `lua_replace` overwrites a stack slot. If that stack slot contained the
>>>
>>> last reference to a value, that value has to be finalized. The same
>>> applies
>>> to `lua_pop`, `lua_remove`, `lua_copy`, `lua_xmove`, `lua_rawget`,
>>> `lua_next`, etc.
>>>
>>> It is not the slots that should have ref counts. Slots stay what they are.
>>> It is the objects (userdata and tables) that should have ref counts
>>
>>
>> I'm not sure I can follow. When would you update the reference counts?
>
> When the object is assigned to a stack slot, when it's removed from a
> stack slot, when it's assigned to a table field, when it's removed
> from a table field, when it's assigned to a table key, when it's used
> as a key to store nil into a table, when a table that contains it is
> destroyed. The exceptions are weak tables, where being assigned as a
> weak key/value does not modify the refcount (but has to track a
> backpointer to clean it up).

That's what I assumed, but then `lua_replace` (and the others
mentioned), which overwrites a stack slot, can cause a reference count
to become 0.

>
> /s/ Adam
>

Philipp



Reply | Threaded
Open this post in threaded view
|

Re: block-scope finalization

Dibyendu Majumdar
In reply to this post by Coda Highland
On 24 November 2015 at 20:45, Coda Highland <[hidden email]> wrote:

>>> What is wrong with the following proposal?
>>>
>>>   local <some mark to be invented> name = exp
>>>
>>> Unlike a regular 'local' declaration, this one must define only one
>>> variable and it must be initialized. (Both restrictions could be easily
>>> removed; they are more about programming style.)
>>>
>>> When the local 'name' goes out of scope, then:
>>>
>>> 1 - if its value is a function, that function is called (no parameters)
>>> 2 - if its value is a table/userdata, its __close (or some other new
>>> name) metamethod, if present, is called.
>>>
>>> Otherwise, 'name' is like any other local variable.
>>>
>>
>> I haven't followed the whole conversation so apologies if I have got
>> this wrong. If the aim is to provide a 'finally' type feature then an
>> important aspect is that the finally code must execute even when
>> exceptions occur. In the above proposal how will Lua ensure that the
>> function will always be called when the block exits even if there was
>> an exception which jumped down the stack?
>>
>
> Because "going out of scope" is really just another name for "is
> popped off the stack." If an error unwinds the stack, then it would
> have to check for the presence of these marked slots on the way down
> instead of just changing the stack top index.
>

I understand that - but Lua does a longjmp when exceptions are thrown.
Are you saying that the location where the exception is caught (via
setjmp) the stack would be walked up and these functions executed?
Regards

Reply | Threaded
Open this post in threaded view
|

Re: block-scope finalization

Coda Highland
On Tue, Nov 24, 2015 at 12:54 PM, Dibyendu Majumdar
<[hidden email]> wrote:

> On 24 November 2015 at 20:45, Coda Highland <[hidden email]> wrote:
>>>> What is wrong with the following proposal?
>>>>
>>>>   local <some mark to be invented> name = exp
>>>>
>>>> Unlike a regular 'local' declaration, this one must define only one
>>>> variable and it must be initialized. (Both restrictions could be easily
>>>> removed; they are more about programming style.)
>>>>
>>>> When the local 'name' goes out of scope, then:
>>>>
>>>> 1 - if its value is a function, that function is called (no parameters)
>>>> 2 - if its value is a table/userdata, its __close (or some other new
>>>> name) metamethod, if present, is called.
>>>>
>>>> Otherwise, 'name' is like any other local variable.
>>>>
>>>
>>> I haven't followed the whole conversation so apologies if I have got
>>> this wrong. If the aim is to provide a 'finally' type feature then an
>>> important aspect is that the finally code must execute even when
>>> exceptions occur. In the above proposal how will Lua ensure that the
>>> function will always be called when the block exits even if there was
>>> an exception which jumped down the stack?
>>>
>>
>> Because "going out of scope" is really just another name for "is
>> popped off the stack." If an error unwinds the stack, then it would
>> have to check for the presence of these marked slots on the way down
>> instead of just changing the stack top index.
>>
>
> I understand that - but Lua does a longjmp when exceptions are thrown.
> Are you saying that the location where the exception is caught (via
> setjmp) the stack would be walked up and these functions executed?
> Regards
>

Ugh. That's a good point. I forgot that Lua uses the C stack in
addition to its own; I've gotten too accustomed to stackless VMs.

There's probably a way to deal with it. I don't know enough about
Lua's specifics to suggest an implementation.

/s/ Adam

Reply | Threaded
Open this post in threaded view
|

Re: block-scope finalization

Dibyendu Majumdar
On 24 November 2015 at 20:59, Coda Highland <[hidden email]> wrote:

>>>>> What is wrong with the following proposal?
>>>>>
>>>>>   local <some mark to be invented> name = exp
>>>>>
>>>>> Unlike a regular 'local' declaration, this one must define only one
>>>>> variable and it must be initialized. (Both restrictions could be easily
>>>>> removed; they are more about programming style.)
>>>>>
>>>>> When the local 'name' goes out of scope, then:
>>>>>
>>>>> 1 - if its value is a function, that function is called (no parameters)
>>>>> 2 - if its value is a table/userdata, its __close (or some other new
>>>>> name) metamethod, if present, is called.
>>>>>
>>>>> Otherwise, 'name' is like any other local variable.
>>>>>
>>>>
>>>> I haven't followed the whole conversation so apologies if I have got
>>>> this wrong. If the aim is to provide a 'finally' type feature then an
>>>> important aspect is that the finally code must execute even when
>>>> exceptions occur. In the above proposal how will Lua ensure that the
>>>> function will always be called when the block exits even if there was
>>>> an exception which jumped down the stack?
>>>>
>>>
>>> Because "going out of scope" is really just another name for "is
>>> popped off the stack." If an error unwinds the stack, then it would
>>> have to check for the presence of these marked slots on the way down
>>> instead of just changing the stack top index.
>>>
>>
>> I understand that - but Lua does a longjmp when exceptions are thrown.
>> Are you saying that the location where the exception is caught (via
>> setjmp) the stack would be walked up and these functions executed?
>> Regards
>>
>
> Ugh. That's a good point. I forgot that Lua uses the C stack in
> addition to its own; I've gotten too accustomed to stackless VMs.
>
> There's probably a way to deal with it. I don't know enough about
> Lua's specifics to suggest an implementation.
>

I do not think it is possible to implement this without changing the
way exceptions are managed in Lua. And without correct handling of
exceptions this feature is meaningless.

FYI here is the Java semantics:

If the try statement has a finally clause, then another block of code
is executed, no matter whether the try block completes normally or
abruptly, and no matter whether a catch clause is first given control.

The same is true for other languages that offer this.

Also C++ destructors have the same guarantee of being executed -
except that there is added complication of unconstructed objects.

In my opinion, the finally approach is better in garbage collected
languages, but to implement that correctly would mean big changes to
Lua (i.e. no longjmp). Also the C api would have to offer a way to
detect exceptions and throw exceptions - in Java the JNI offers these
capabilities.

Regards

Reply | Threaded
Open this post in threaded view
|

Re: block-scope finalization

Patrick Donnelly
In reply to this post by Dibyendu Majumdar
On Tue, Nov 24, 2015 at 3:54 PM, Dibyendu Majumdar
<[hidden email]> wrote:

> On 24 November 2015 at 20:45, Coda Highland <[hidden email]> wrote:
>>>> What is wrong with the following proposal?
>>>>
>>>>   local <some mark to be invented> name = exp
>>>>
>>>> Unlike a regular 'local' declaration, this one must define only one
>>>> variable and it must be initialized. (Both restrictions could be easily
>>>> removed; they are more about programming style.)
>>>>
>>>> When the local 'name' goes out of scope, then:
>>>>
>>>> 1 - if its value is a function, that function is called (no parameters)
>>>> 2 - if its value is a table/userdata, its __close (or some other new
>>>> name) metamethod, if present, is called.
>>>>
>>>> Otherwise, 'name' is like any other local variable.
>>>>
>>>
>>> I haven't followed the whole conversation so apologies if I have got
>>> this wrong. If the aim is to provide a 'finally' type feature then an
>>> important aspect is that the finally code must execute even when
>>> exceptions occur. In the above proposal how will Lua ensure that the
>>> function will always be called when the block exits even if there was
>>> an exception which jumped down the stack?
>>>
>>
>> Because "going out of scope" is really just another name for "is
>> popped off the stack." If an error unwinds the stack, then it would
>> have to check for the presence of these marked slots on the way down
>> instead of just changing the stack top index.
>>
>
> I understand that - but Lua does a longjmp when exceptions are thrown.
> Are you saying that the location where the exception is caught (via
> setjmp) the stack would be walked up and these functions executed?
> Regards

Lua already does that when closing upvalues, in luaF_close. This
proposal would probably be implemented by expanding luaF_close's
purpose to also call the __close metamethod on these new types of
locals. Fortunately a lot of the work for closing upvalues overlaps
here.

--
Patrick Donnelly

Reply | Threaded
Open this post in threaded view
|

Re: block-scope finalization

Coda Highland
In reply to this post by Dibyendu Majumdar
On Tue, Nov 24, 2015 at 1:05 PM, Dibyendu Majumdar
<[hidden email]> wrote:

> On 24 November 2015 at 20:59, Coda Highland <[hidden email]> wrote:
>>>>>> What is wrong with the following proposal?
>>>>>>
>>>>>>   local <some mark to be invented> name = exp
>>>>>>
>>>>>> Unlike a regular 'local' declaration, this one must define only one
>>>>>> variable and it must be initialized. (Both restrictions could be easily
>>>>>> removed; they are more about programming style.)
>>>>>>
>>>>>> When the local 'name' goes out of scope, then:
>>>>>>
>>>>>> 1 - if its value is a function, that function is called (no parameters)
>>>>>> 2 - if its value is a table/userdata, its __close (or some other new
>>>>>> name) metamethod, if present, is called.
>>>>>>
>>>>>> Otherwise, 'name' is like any other local variable.
>>>>>>
>>>>>
>>>>> I haven't followed the whole conversation so apologies if I have got
>>>>> this wrong. If the aim is to provide a 'finally' type feature then an
>>>>> important aspect is that the finally code must execute even when
>>>>> exceptions occur. In the above proposal how will Lua ensure that the
>>>>> function will always be called when the block exits even if there was
>>>>> an exception which jumped down the stack?
>>>>>
>>>>
>>>> Because "going out of scope" is really just another name for "is
>>>> popped off the stack." If an error unwinds the stack, then it would
>>>> have to check for the presence of these marked slots on the way down
>>>> instead of just changing the stack top index.
>>>>
>>>
>>> I understand that - but Lua does a longjmp when exceptions are thrown.
>>> Are you saying that the location where the exception is caught (via
>>> setjmp) the stack would be walked up and these functions executed?
>>> Regards
>>>
>>
>> Ugh. That's a good point. I forgot that Lua uses the C stack in
>> addition to its own; I've gotten too accustomed to stackless VMs.
>>
>> There's probably a way to deal with it. I don't know enough about
>> Lua's specifics to suggest an implementation.
>>
>
> I do not think it is possible to implement this without changing the
> way exceptions are managed in Lua. And without correct handling of
> exceptions this feature is meaningless.
>
> FYI here is the Java semantics:
>
> If the try statement has a finally clause, then another block of code
> is executed, no matter whether the try block completes normally or
> abruptly, and no matter whether a catch clause is first given control.
>
> The same is true for other languages that offer this.
>
> Also C++ destructors have the same guarantee of being executed -
> except that there is added complication of unconstructed objects.
>
> In my opinion, the finally approach is better in garbage collected
> languages, but to implement that correctly would mean big changes to
> Lua (i.e. no longjmp). Also the C api would have to offer a way to
> detect exceptions and throw exceptions - in Java the JNI offers these
> capabilities.

I don't think longjmp is a problem, in and of itself. Microsoft used
setjmp/longjmp to implement C++ exception handling and was able to
clean up after itself. They switched to a better implementation later,
yes, but it's still possible. The important bit, I think, is that
setjmp/longjmp isn't part of the exposed Lua API, but instead the Lua
internals are able to set up whatever information they need before the
longjmp call and between the return to setjmp and the invocation of
the panic handler or the resumption of the pcall.

Yeah, we'd be out of luck if the host used setjmp/longjmp for its own
purposes, but I don't think that's any different than now.

/s/ Adam

Reply | Threaded
Open this post in threaded view
|

Re: block-scope finalization

Dibyendu Majumdar
On 24 November 2015 at 21:10, Coda Highland <[hidden email]> wrote:

> I don't think longjmp is a problem, in and of itself. Microsoft used
> setjmp/longjmp to implement C++ exception handling and was able to
> clean up after itself. They switched to a better implementation later,
> yes, but it's still possible. The important bit, I think, is that
> setjmp/longjmp isn't part of the exposed Lua API, but instead the Lua
> internals are able to set up whatever information they need before the
> longjmp call and between the return to setjmp and the invocation of
> the panic handler or the resumption of the pcall.
>

Agreed but I once did a home grown exception handling using longjmp
and I think the implementation is not at all pretty. Every time a
'try' clause is entered, an object needs to be put on the stack linked
to the previous such object - then there has to be a setjmp within the
try block. When the code exits the block or an exception is thrown,
the code needs to longjmp to this setmp, execute any destructors or
finally code, and then allow normal return. How will all that
machinary work in lua in the presence of C functions all over the
place?

> Yeah, we'd be out of luck if the host used setjmp/longjmp for its own
> purposes, but I don't think that's any different than now.
>

In Microsoft's current C++ implementation, longjmp is also tied to the
exception unwind mechanism.

Regards

Reply | Threaded
Open this post in threaded view
|

Re: block-scope finalization

Coda Highland
On Tue, Nov 24, 2015 at 1:16 PM, Dibyendu Majumdar
<[hidden email]> wrote:

> On 24 November 2015 at 21:10, Coda Highland <[hidden email]> wrote:
>
>> I don't think longjmp is a problem, in and of itself. Microsoft used
>> setjmp/longjmp to implement C++ exception handling and was able to
>> clean up after itself. They switched to a better implementation later,
>> yes, but it's still possible. The important bit, I think, is that
>> setjmp/longjmp isn't part of the exposed Lua API, but instead the Lua
>> internals are able to set up whatever information they need before the
>> longjmp call and between the return to setjmp and the invocation of
>> the panic handler or the resumption of the pcall.
>>
>
> Agreed but I once did a home grown exception handling using longjmp
> and I think the implementation is not at all pretty. Every time a
> 'try' clause is entered, an object needs to be put on the stack linked
> to the previous such object - then there has to be a setjmp within the
> try block. When the code exits the block or an exception is thrown,
> the code needs to longjmp to this setmp, execute any destructors or
> finally code, and then allow normal return. How will all that
> machinary work in lua in the presence of C functions all over the
> place?

Never said it was pretty, but your description sounds about like what
I was expecting.

/s/ Adam

Reply | Threaded
Open this post in threaded view
|

Re: block-scope finalization

Viacheslav Usov
In reply to this post by Philipp Janda
On Tue, Nov 24, 2015 at 9:53 PM, Philipp Janda <[hidden email]> wrote:

> That's what I assumed, but then `lua_replace` (and the others mentioned), which overwrites a stack slot, can cause a reference count to become 0.

An object's reference count is not directly affected by doing anything to stack slots. Some additional logic is required to manipulate the reference counts of the objects involved. This logic needs to be correct. If you think it can never be correct in certain cases, please give us an example illustrating your point.

Cheers,
V.

Reply | Threaded
Open this post in threaded view
|

Re: block-scope finalization

Roberto Ierusalimschy
In reply to this post by Patrick Donnelly
> Lua already does that when closing upvalues, in luaF_close. This
> proposal would probably be implemented by expanding luaF_close's
> purpose to also call the __close metamethod on these new types of
> locals. Fortunately a lot of the work for closing upvalues overlaps
> here.

Exactly. A "local <new name>" will create an upvalue just like a closure,
but with an extra bit telling "I need finalization". Then, luaF_close
checks that bit when closing upvalues and call the appropriate functions
when needed. (The implementation would be trivial; what makes things
more complex is handling errors inside those functions.)

-- Roberto

Reply | Threaded
Open this post in threaded view
|

Re: block-scope finalization

Tomás Guisasola-2
In reply to this post by Roberto Ierusalimschy
Hi

> 1 - if its value is a function, that function is called (no parameters)
Ok, but, IMHO, it seems an overkill.  You could stay with the second
case for functions too...

> 2 - if its value is a table/userdata, its __close (or some other new
> name) metamethod, if present, is called.
What's the problem with the __gc metamethod?

Regards,
Tomás

12345