[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Deprecating setfenv()
- From: Mark Hamburg <mark@...>
- Date: Sat, 9 Jan 2010 17:35:49 -0800
On Jan 9, 2010, at 5:22 PM, Mark Hamburg wrote:
> Now that I've spent a little more time looking at the Lua internals, I start to wonder why Lua doesn't store the environment in the CallInfo and just use the value attached to the closure as part of the CallInfo initialization. This was the semantics that the stack indexing for setfenv/getfenv had led me to expect though the manual said otherwise. It is also the semantics that would map cleanly to what "in env do end" is doing. It would also readily enable a call_with_environment construct which would override the environment in the closure on a temporary basis thereby handling Leo's use case.
>
> If it just needs to work for Lua closures, then the space is already available in CallInfo. If it needs to work for C closures as well, then CallInfo will have to get bigger which is a bit of a performance hit. That, however, saves needing to look in two different places in getcurrenv. Other than the potential call info size issue and the need to initialize one more field on a function call, a scan of the code indicates that this shouldn't be a performance hit.
>
> If it did work for C code as well, this would also make the C code for table.pack safe with respect to GC leaks. The current code leaves the last packed result hanging around in the environment for the pack function.
Specifically, consider the following as an alternative to setfenv:
in special_environment do
call_with_current_environment( f, arg, arg, arg ) -- envcall? ecall?
end
I'm also trying to think of a reasonable way to provide support for current getfenv uses that doesn't have security issues. Specifically, how does one make it reasonable to write something like the import function cited earlier in this discussion (dumps the contents of a table returned by require into the caller's environment) or the various class construction routines used in Ruby classes (particularly things like ActiveRecord's hasOne, etc.).
Mark