获取Lua脚本中的所有函数

我正在尝试找出一种方法来获取Lua脚本中的所有函数。这个脚本已经通过loadfile编译成为一个函数。例如,我想要获取下面脚本中定义的每个函数。

function example1()

end

local function example2()

end

local library = {}

function library:example3()

end

(function()
    -- 像这样的函数也一样。
end)

名字并不重要,我只是想找到一种方法来获取实际的函数,以便在debug.getinfo中使用它们并获取它们定义的行信息。我有LuaJIT,如果这能让事情变得更容易。这样的事情甚至可能吗?谢谢。

点赞
用户6245072
用户6245072

我猜测这个文件将它的函数声明为全局的,否则很容易跟踪返回什么。

如果是这种情况,你可以用通用的for循环遍历所有全局项,只取它们的函数:

allFuncs = {}

for key, item in pairs(_G) do
    if type(item) == "function" then
        allFuncs[#allFuncs + 1] = item
    end
end

( _G 是包含所有全局变量的表)

接下来你将会有一个列表(allFuncs),里面包含所有被声明的函数,但要注意它也会包括默认函数,如 setmetatablexpcall

你可以很容易地修改这段代码以避免这种情况,但只用于测试/学习:

function allFuncs()
    local funcsTab = {}
    for key, item in pairs(_G) do
        if type(item) == "function" then
            funcsTab[#funcsTab + 1] = item
        end
    end
    return funcsTab
end

defaultFuncs = allFuncs()

--然后你加载你的文件:其他函数被声明
--我们创建另一个表来包含默认函数和新函数

myFuncs = allFuncs()

--然后你从第二个表中减去第一个表

for i = 1, #myFuncs do
    for o = 1, #defaultFuncs do
        if myFuncs[i] == defaultFuncs[o] then
            table.remove(myFuncs, i)
        end
    end
end

如果你的文件未返回任何内容且将其函数声明为全局的,则如上所示处理。

如果文件将它们声明为局部变量然后返回包含它们的一个表,则只需使用第一段代码,将 _G 替换为返回的那个表。

2016-05-18 21:13:55
用户1442917
用户1442917

这可能需要使用语法或字节码分析来实现,因为每个函数定义都是一个赋值(在你的例子中只是形式不同)。可以参考字节码探测器和相关讨论在这里。对于语法分析,可以使用metalua或类似的lu-loose-parser。请记住,即使使用这些工具,也无法获得所有函数的完整列表,因为某些函数可能使用loadstring(或类似的方法)动态定义。

如果您只能访问loadfile的结果,则最好使用字节码分析器。

2016-05-19 00:39:09
用户15091169
用户15091169

这可以通过 LuaJIT 中的 jit.attach 实现。

您可以使用 jit.attach 将回调函数附加到多个编译器事件上。回调函数可以在以下情况下调用:

  • 函数编译为字节码时(“bc”);
  • 跟踪记录开始或停止时(“trace”);
  • 记录跟踪时(“record”);
  • 或当跟踪通过侧面退出时(“texit”)。

http://wiki.luajit.org/JIT-Compiler-API#jit-attach

jit.attach(function(f)
    local funcInfo = jit.util.funcinfo(f)
end, "bc")
2021-01-27 11:36:55