Muh Muhten
2018-11-18 23:53:30 UTC
Hello,
In light of a perennial topic.
Recently, I put together Yet Another attempt at, essentially,
identifying uses of global variables. The approach is essentially
external static analysis on bytecode, but implemented to be practical
and ergonomic to perform during execution: it exports a function to
check the caller. Overhead seems to be relatively light can be
isolated to startup. The downside is, of course, sensitivity to
internal data structures (the precompiled chunk representation).
WIP code: https://gist.github.com/muhmuhten/f469d25d375e4e742b74c7a938c58ac8
A few areas where I would particularly appreciate feedback:
- Am I surfacing a useful concept of a global access which solves an
actual problem?
- Is this approach *overzealous* in preventing useful operations?
(An important consideration. Earlier I considered using debug
information to check whether the table whose fields were accessed was
named _ENV. But this requires nasty things to be done to nice code in
the vein of function (_ENV) return x^2+y^2 end.)
- It is my understanding that a chunk is compiled with a single
upvalue with instack==1, idx==0, and the variables a function closes
over depend on its upvalues. In particular, upvalues not "instack"
refer to in the idx-th upvalue slot of the containing function. I
follow this chain of upvalue indices down to determine whether the
table being accessed by a given GET/SETTABUP is the toplevel _ENV.
- Does reading dumped chunks in this manner seem robust?
For the most part, I expect to be reading structures from the local
Lua instance, using its own table.unpack to figure out the proper
sizes, byte order &c.. But I have not tested it on different
machines, let alone the range of systems Lua will build on.
Of course, any other considerations I may have overlooked.
I am open to name suggestions :-)
Best,
Michael
In light of a perennial topic.
Recently, I put together Yet Another attempt at, essentially,
identifying uses of global variables. The approach is essentially
external static analysis on bytecode, but implemented to be practical
and ergonomic to perform during execution: it exports a function to
check the caller. Overhead seems to be relatively light can be
isolated to startup. The downside is, of course, sensitivity to
internal data structures (the precompiled chunk representation).
WIP code: https://gist.github.com/muhmuhten/f469d25d375e4e742b74c7a938c58ac8
A few areas where I would particularly appreciate feedback:
- Am I surfacing a useful concept of a global access which solves an
actual problem?
- Is this approach *overzealous* in preventing useful operations?
(An important consideration. Earlier I considered using debug
information to check whether the table whose fields were accessed was
named _ENV. But this requires nasty things to be done to nice code in
the vein of function (_ENV) return x^2+y^2 end.)
- It is my understanding that a chunk is compiled with a single
upvalue with instack==1, idx==0, and the variables a function closes
over depend on its upvalues. In particular, upvalues not "instack"
refer to in the idx-th upvalue slot of the containing function. I
follow this chain of upvalue indices down to determine whether the
table being accessed by a given GET/SETTABUP is the toplevel _ENV.
- Does reading dumped chunks in this manner seem robust?
For the most part, I expect to be reading structures from the local
Lua instance, using its own table.unpack to figure out the proper
sizes, byte order &c.. But I have not tested it on different
machines, let alone the range of systems Lua will build on.
Of course, any other considerations I may have overlooked.
I am open to name suggestions :-)
Best,
Michael