3

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.

3 Answers 3

4

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.

Sign up to request clarification or add additional context in comments.

2 Comments

The script is going to be dynamic (it comes from somewhere else, user created), and I need to get every function defined in that script, not every global function. Thank you, though!
Ok, but how does that script declare the functions? Does it declare them as local, and then return them in a table? Or does it just declare them as global functions, without returning anything? If it does return a table, you can use the code above replacing _G with that returned table.
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.

Comments

1

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.