Getting all functions in a Lua script

≡放荡痞女 提交于 2021-02-05 06:52:10

问题


I'm trying to figure out a way to get all functions in a Lua script. This script has been compiled into a function through loadfile. For example, I'd want to get every function defined in the script below.

function example1()

end

local function example2()

end

local library = {}

function library:example3()

end

(function()
    -- Functions like this too.
end)

The names aren't important, I'm just looking for a way to get the actual functions so I can use them in debug.getinfo and get information like the lines they were defined in. I have LuaJIT, if that makes this any easier. Is something like this even possible? Thanks in advance.


回答1:


This is not likely to be possible without syntax or bytecode analysis as each function definition is an assignment (just has different forms in your examples). See the bytecode inspector and a related discussion here. For the syntax analysis you can use metalua or something like lua-loose-parser. Keep in mind that even those tools won't give you the entire list of functions as some functions may be defined dynamically using loadstring (or similar methods).

If you only have access to the result of loadfile, then you best bet is to use the bytecode analyzer.




回答2:


I guess the file declares its functions as global, or it would be really easy to track what is returned.

If that's the case, you can cycle through all the global items with a generic for loop, and only take the functions from them:

allFuncs = {}

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

(_G is the table holding all the global variables)

Then you will have a list (allFuncs) holding all the functions declared, but be aware that it will also contain default functions like setmetatable or xpcall.

It's easy to modify the code to not make this happen, but only use this for testing / learning:

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()

--then you load your file: other functions get declared
--we create another table containg the default + the new functions

myFuncs = allFuncs()

--then you subtract the first table from the second

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

This is if your file doesn't return anything and declares its functions as globals.

If the file declares them as local and then returns a table containing them, just use the first piece of code replacing _G with that returned table.




回答3:


This is possible using jit.attach in LuaJIT.

You can attach callbacks to a number of compiler events with jit.attach. The callback can be called:

  • when a function has been compiled to bytecode ("bc");
  • when trace recording starts or stops ("trace");
  • as a trace is being recorded ("record");
  • or when a trace exits through a side exit ("texit").

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

jit.attach(function(f)
    local funcInfo = jit.util.funcinfo(f)
end, "bc")


来源:https://stackoverflow.com/questions/37309901/getting-all-functions-in-a-lua-script

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!