lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On 11/27/18, Sean Conner <sean@conman.org> wrote:
> (if not outright impossible in some cases).

In some cases, it is outright impossible, in the sense that deciding
which upvalue was _ENV is not a function of the code.

Consider the examples I give for
<https://gist.github.com/f469d25d375e4e742b74c7a938c58ac8#limitations>:
the only way to tell the difference is to actually check the upvalues,
and see that one of them is the same as the global table. Of course,
this is not guaranteed either if _ENV is redefined.

What I believe you *could* do is, on finding an upvalue which is the
global table, debug.upvaluejoin it to the first upvalue of a chunk (or
more directly, a throwaway C closure) constructed with the new
environment as its only upvalue. I have not tried it. It probably
breaks expected semantics in all sort of subtle ways.

It's probably for the best to accept that fenv semantics are not
implementable in terms of _ENV. This is kind of expectable, since part
of the rationale for the change was (paraphrasing) that the setfenv
mechanism was too powerful and more suited to the debug library.

Incidentally, the _ENV mechanism is essentially syntactic sugar and
afaict can be mechanically translated to just introducing a local
named _ENV at the beginning of a chunk and rewriting all would-be
global accesses to index _ENV. There's one tiny difference (it's now a
local, not an upvalue, of the main function) but that seems like a
corner case that will only come up if you use the debug library or
otherwise muck with internals. As such, it might be easier to retarget
the 5.3 compiler to the 5.1 VM(!) if you *need* this functionality.
Certainly 5.2.