[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: LBCI replacement for LuaJIT 2
- From: Alexander Gladysh <agladysh@...>
- Date: Wed, 1 Sep 2010 01:47:09 +0400
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...)
>> Is there a way to implement my function (see below) in current LJ2?
>> I'll settle for non-stable API.
> See: http://lua-users.org/lists/lua-l/2009-11/msg00535.html
A lot of magic constants there. I hope that you will mention in the
changelog if you change the API :-)
> The opcodes you're looking for are GGET and GSET. The table
> returned by jit.util.funcinfo() has the field "upvalues", which
> contains the number of upvalues.
Thanks! I had to dig around in the LJ2 source a bit, but looks like I
made it. Won a half of a second by transition to LJ2 :-) (Now an
external tool being launched from the code slows down things, but it
is another story.)
See my implementation below, perhaps it will be useful for someone
else. (It is not completely equivalent to my original code — I did
some refatoring to abstract the actual inspection method.)
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