如何从Lua脚本中获取有关函数调用的信息?
2021-3-18 10:29:38
收藏:0
阅读:152
评论:1
我有一个用Lua 5.1编写的脚本,导入了第三方模块并从中调用了一些函数。我想要获取一个带有参数列表(当它们在执行之前已知时)的模块内函数调用列表。
因此,我需要编写另一个脚本,它接收我第一个脚本的源代码,对其进行解析,并从其中提取信息。
请考虑以下最小示例。
我有以下模块:
local mod = {}
function mod.foo(a, ...)
print(a, ...)
end
return mod
和以下驱动程序代码:
local M = require "mod"
M.foo('a', 1)
M.foo('b')
有什么更好的方法可以检索带有“使用”'M.foo'函数的数据?
理想情况下,我想获取被调用的函数名和其参数值的信息。从上面的示例代码中,只需要得到像这样的映射:{'foo':[('a',1),('b')]}。
我不确定Lua是否有用于反射检索此信息的函数。因此,可能需要使用Lua的现有解析器之一来获取完整的AST,并查找我感兴趣的函数调用。
还有其他建议吗?
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

如果无法修改文件,则可以将文件读取为字符串,然后解析
mod文件并查找其中所有函数,然后使用该信息来解析目标文件以查找 mod 库的所有用法。functions = {} for func in modFile:gmatch("function mod%.(%w+)") do functions[func] = {} end for func, call in targetFile:gmatch("M%.(%w+)%(([^%)]+)%)") do args = {} for arg in string.gmatch(call, "([^,]+)") do table.insert(args, arg) end table.insert(functions[func], args) end最终的表可以序列化成如下格式:
['foo'] = {{"'a'", " 1"}, {"'b'"}}有三个可能会出现问题的地方:
M不是一个非常唯一的名字,可能会匹配到另一个库的意想不到的函数调用。myfunc(getStuff(), true)。如果可以修改目标文件,则可以在您的必需模块周围创建一个包装器。
function log(mod) local calls = {} local wrapper = { __index = function(_, k) if mod[k] then return function(...) calls[k] = calls[k] or {} table.insert(calls[k], {...}) return mod[k](...) end end end, } return setmetatable({},wrapper), calls end然后您可以像这样使用此函数。
local M, calls = log(require("mod")) M.foo('a', 1) M.foo('b')如果您的模块不仅仅是
function,则需要在包装器中处理它,该包装器假定所有索引都是函数。在所有调用之后,可以将
calls表序列化以获取所有调用的历史记录。对于示例代码,表如下所示:{ ['foo'] = {{'a', 1}, {'b'}} }