使用Lua访问函数体

时间:2009-02-02 18:36:22

标签: function debugging lua function-pointers visualizer

我要回到这里的基础知识,但在Lua中,你可以像这样定义一个表:

myTable = {}
myTable [1] = 12

打印表引用本身会返回指向它的指针。要访问其元素,您需要指定一个索引(即与数组完全一样)

print(myTable )    --prints pointer
print(myTable[1])  --prints 12

现在功能是另一回事。您可以定义和打印如下函数:

myFunc = function() local x = 14 end     --Defined function
print(myFunc)                            --Printed pointer to function

有没有办法访问已定义函数的主体。我试图整理一个小代码可视化器,并希望用特殊的函数/变量“播种”给定的函数,以允许可视化器将自己“挂钩”到代码中,我需要能够重新定义函数。变量或字符串。

4 个答案:

答案 0 :(得分:10)

无法在普通Lua中访问给定函数的正文源代码。编译成字节码后,源代码被丢弃。

注意BTW可以在运行时使用类似于loadstring的工具定义函数。

部分解决方案是可行的 - 取决于您实际想要实现的目标。

您可以从调试库获取源代码位置 - 如果启用了调试库并且未从字节码中删除调试符号。之后,您可以加载实际的源文件并从那里提取代码。

您可以使用所需的元数据手动装饰您感兴趣的功能。请注意,Lua中的函数是有效的表键,因此您可以创建函数到元数据表。您可能希望将此表设置为弱键,因此不会阻止GC收集函数。

如果您需要分析Lua代码的解决方案,请查看Metalua

答案 1 :(得分:4)

使用调试库是您唯一的选择。使用它,您可以获得字符串(如果函数是在加载了'loadstring'的块中定义的)或者是定义函数的文件的名称;以及函数定义开始和结束的行号。请参阅documentation

在我目前的工作中,我们修补了Lua,它甚至为您提供了函数开始和结束的列号,因此您可以使用它来获取函数源。补丁不是很难重现,但我不认为我会在这里发布: - (

答案 2 :(得分:2)

在调试库中查看Lua Introspective Facilities

  

主要内省功能   debug库是debug.getinfo   功能。它的第一个参数可能是a   功能或堆栈级别。当你   为某些人调用debug.getinfo(foo)   功能foo,你得到一张桌子   关于该功能的一些数据。该   表可能包含以下字段:

你想要的领域是我认为的功能。

答案 3 :(得分:0)

您可以通过为每个函数创建environment(请参阅setfenv)并使用全局(与本地)变量来实现此目的。执行该函数后,函数中创建的变量将出现在环境表中。

env = {}
myFunc = function() x = 14 end
setfenv(myFunc, env)
myFunc()
print(myFunc)    -- prints pointer
print(env.x)     -- prints 14

或者,您可以使用Debug Library

> myFunc = function() local x = 14 ; debug.debug() end
> myFunc()
> lua_debug> _, x = debug.getlocal(3, 1)
> lua_debug> print(x) -- prints 14

使用hook function检索局部变量而不是显式进入调试模式(即添加debug.debug()调用)可能更有用

Lua C API中还有一个Debug Interface