lua-users home
lua-l archive

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


> Isn't there enough information in 'luac -p -l' to distinguish between various access?

There isn't enough information in 'luac -p -l' but there is in 'luac -p -l -l'.
However, the list of locals is printed after the bytecode and one would need
to read the whole listing to find SETTABLE and GETTABLE that use a local
named _ENV.

This particular task is easier to program with lbci. The code at the end
shows an example. However, it does not works in all cases; it is fooled
by this code:

do
  do local x,y,z end	-- _ENV will use the same slot as x
  local _ENV = {}
  _NAME = 'BAZ'
  function Foo() if _NAME then return end end
  function Bar() Foo() end
end

To fix this requires a more sophisticaed look at the list of locals, taking
end of scope into consideration. All this information is available both in
luac long listings and via lci.

Here is the lbci code for the simple case.

local inspector=require"bci"
local function globals(f,all)
 local F=inspector.getheader(f)
 for i=1,F.instructions do
  local a,b,c,d,e=inspector.getinstruction(f,i)
  if b=="GETTABUP" and inspector.getupvalue(f,d+1)=="_ENV" then
   print("",F.source,a,"GET ",inspector.getconstant(f,-e))
  elseif b=="SETTABUP" and inspector.getupvalue(f,c+1)=="_ENV" then
   print("",F.source,a,"SET*",inspector.getconstant(f,-d))
  elseif b=="GETTABLE" and inspector.getlocal(f,d+1)=="_ENV" then
   print("",F.source,a,"GET ",inspector.getconstant(f,-e))
  elseif b=="SETTABLE" and inspector.getlocal(f,c+1)=="_ENV" then
   print("",F.source,a,"SET*",inspector.getconstant(f,-d))
  end
 end
 if all then
  for i=1,F.functions do
   globals(inspector.getfunction(f,i),all)
  end
 end
end