lua-users home
lua-l archive

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


On Fri, Dec 21, 2018 at 10:47 PM Jonathan Goble <jcgoble3@gmail.com> wrote:
Can a function (Lua or C) in Lua 5.2+ gain access to its caller's _ENV, and if so, can it modify that table and/or replace that table with a new one? I know access and modification are trivial if you require passing the _ENV table as an argument, and replacement is trivial if you simply return a table that documentation specifies must be assigned to _ENV. I'm not interested in those simple "tricks".

What I'm looking for is an approach that allows all three (access, modify, and replace) without writing "_ENV" (or the name of any variable that refers to _ENV) anywhere in the statement that calls the function. I'm open to any solution, including complicated debug library hacks and/or the C API, as long as it would work consistently. Bonus points for a single approach that works on 5.2, 5.3, and the 5.4work git HEAD with minimal or no branching to deal with differences between versions.

Any thoughts on how to do this? Or is it not possible?

I played around in the REPL and think I've figured it out. debug.getupvalue and debug.setupvalue (and their C equivalents) give the ability to access and replace the upvalues of an arbitrary function, but need the function object itself rather than a stack level. To get the calling function, debug.getinfo with "uf" for the "what" parameter and 2 for the stack level gives me the caller and its number of upvalues. Then I pass the function to debug.getupvalue with each index up to the number of upvalues until I find the one I want. Finally, I can directly mutate the table, or replace it with another using debug.setupvalue with the same index. I haven't tried changing _ENV yet, but this has worked with other upvalues, so I assume it will work with _ENV as well.

*puts on mad scientist hat* Might attempt an interesting project during the break between semesters.