[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Looking for some help - add fenv and other 5.1 features to ravi-distro
- From: Sean Conner <sean@...>
- Date: Tue, 27 Nov 2018 22:21:52 -0500
It was thus said that the Great Tim Hill once stated:
>
>
> > On Nov 27, 2018, at 3:04 PM, Sean Conner <sean@conman.org> wrote:
> >
> > So any code loaded via load() (or similar) will hvae _ENV as the first
> > upvalue, you can use setupvalue() to switch out the _ENV value currently
> > set. Arbitrary functions might be a bit harder to locate the proper _ENV to
> > swap (if not outright impossible in some cases).
>
> Sadly that’s not true. Any chunk that is COMPILED will honor this, but
> code that is obtained via string.dump() followed by load() often will not.
> Such a dumped function may or may not have _ENV as one of its upvalues,
> and even if it does, it may not be the first.
I think there's a bug in the description for string.dump(). It states,
"[w]hen (re)loaded, those upvalues receive fresh instances containing nil."
But load() states "When you load a main chunk, the resulting function will
always have exactly one upvalue, the _ENV variable (see §2.2). However, when
you load a binary chunk created from a function (see string.dump), the
resulting function can have an arbitrary number of upvalues."
Running this:
local function upvals(name,f)
local function upv(i)
local n,v = debug.getupvalue(f,i)
if v then
print("",i,n,v)
return upv(i+1)
end
end
print(name)
upv(1)
end
local a = 0
local function foo(x)
a = a + 1
print(x)
print(os.getenv(x))
return a
end
upvals("foo",foo)
local dumped = string.dump(foo)
local reloaded = load(dumped)
upvals("reloaded",reloaded)
I get:
foo
1 a 0
2 _ENV table: 0x89b5568
reloaded
1 a table: 0x89b5568
So the first upvalue will have _ENV (in this case, the global _ENV), but
not the rest (also, the first upvalue for reloaded() should be a number, not
a table).
-spc (Which presents yet another problem with simulating setfenv() in Lua
5.2 or higher ... hmmm ... perhaps not a good idea after all)