lua-users home
lua-l archive

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


Hi, Mike!

Sorry to revive an old thread, but it gives necessary context.

On Wed, Sep 1, 2010 at 01:47, Alexander Gladysh <agladysh@gmail.com> wrote:
> On Tue, Aug 31, 2010 at 22:23, Mike Pall <mikelu-1008@mike.de> wrote:
>> Alexander Gladysh wrote:

>>> I use it to get a list of GET/SETGLOBAL instructions from a given
>>> function and to get number of upvalues. (Note that in future I'll
>>> probably want to traverse the list of upvalues and check if they're
>>> allowed...)

<...>

> See my implementation below.

Now I need to traverse all nested chunks as well.

That is, my code should be able to get "print" as a global name on this example:

---
local f = function()
  return function()
    print("foo")
  end
end
f()()
---

Can you please hint me how to do this? I was not able to find a
solution by looking at LJ2 code...

Thanks,
Alexander.

>  local update_info = function(self)
>    method_arguments(self)
>
>    self.info_ = self.info_ or assert(
>        jutil.funcinfo(self.chunk_),
>        "not a Lua function"
>      )
>  end
>
>  local update_globals_lists = function(self)
>    method_arguments(self)
>
>    if self.gets_ ~= nil then
>      assert(self.sets_ ~= nil)
>    else
>      assert(self.sets_ == nil)
>
>      self.gets_, self.sets_ = { }, { }
>
>      update_info(self)
>
>      local info = self.info_
>      local chunk = self.chunk_
>
>      for i = 1, info.bytecodes do
>        local ins, m = jutil.funcbc(chunk, i)
>        if not ins then
>          break -- TODO: ?!
>        end
>
>        local oidx = 6 * bit.band(ins, 0xff)
>        local opcode = string_sub(bcnames, oidx + 1, oidx + 6)
>        if opcode == "GGET  " or opcode == "GSET  " then
>          local d = bit.rshift(ins, 16)
>          local name = jutil.funck(chunk, -d - 1)
>
>          local list = (opcode == "GGET  ") and self.gets_ or self.sets_
>
>          local global = list[name]
>          if not global then
>            global = { }
>            list[name] = global
>          end
>
>          global[#global + 1] =
>          {
>            line = jutil.funcinfo(chunk, i).currentline;
>            source = info.source;
>          }
>        end
>      end
>    end
>  end
>