lua-users home
lua-l archive

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


On Wed, Oct 19, 2011 at 1:25 AM, Hisham <hisham.hm@gmail.com> wrote:
> Discussing this offlist with Fabio he also mentioned another benefit
> of module()-style modules: that one can easily inspect the code
> mechanically for global declarations and infer what's exported, while
> module()-less-modules make this kind of static analysis a lot more fragile.

LuaInspect's experience has actually been the opposite.  It can infer
from first principles that the following chunk returns a table
containing a field "baz" having a function value, even though the
coding style is mildly pathological:

local abc = (function() return {} end)()
local x = "b"
if true then
  foo()
  abc[x  .. "az"] = function() foo() end
end
abc['y' .. math.random(10)] = 1
local function gg()
  print 'a'
  return x and abc
end
return gg()

This is done without executing "print 'a'" and without knowing the
definition of "foo" or the return value of math.random(10).  In short
it makes the following inferences, which a human can likewise easily
do:

  - Some values are constant folded.
  - Some locals are inferred to be constant (barring extraordinary
things with the debug library inside foo).
  - Return values or types of some functions are inferred.

Now with the module function, at least in its 5.1 form, LuaInspect
doesn't even attempt to interpret it statically but rather falls back
to a dynamic evaluation in the Lua VM.  Environments with metatables
are more complicated to analyze by a human as well as computer.  Yes,
you could (or even should) feed the analyzer some preconceived
semantics of standard functions like module/package.seeall and assume
nothing tricky like redefinition of these functions has been done, but
this is not derived from first principles. Incidentally, LuaInspect is
fed preconceived static semantics for require, and it assumes that a
global with that name is that function (require is not a keyword in
Lua).  Fortunately, unlike in an optimizing compiler, it's not
catastrophic but rather is helpful for LuaInspect to make such
assumptions.

Yes, Lua 5.2.0-beta's restrictions on environments can also simplify
static analysis:

    _ENV = {}  -- We know lexically that this environment has no
metatable funny business.
    x = 1
    f()  -- Unlike in 5.1, functions are not normally permitted to
alter the caller's environment.
    return x  -- Therefore, we can infer this will always return 1.