函数:{"getlocal", db_getlocal}
从db_getlocal开始跟调.该函数是把自身的所有变量打印出来。大体的思路是算到执行码,根据执行码的大小限制,遍历函数保存的变量信息,然后依次打印。
static int db_getlocal (lua_State *L) {
int arg;
lua_State *L1 = getthread(L, &arg);
lua_Debug ar;
const char *name;
/*
根据level算出L->ci 和 L->base_ci之间的偏差值。见段1
*/
if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
return luaL_argerror(L, arg+1, "level out of range");
/*
这里的ar只是有一个偏移值,具体的还在lua_getlocal里边。见段2
*/
name = lua_getlocal(L1, &ar, luaL_checkint(L, arg+2));
if (name) {
lua_xmove(L1, L, 1);
lua_pushstring(L, name);
lua_pushvalue(L, -2);
return 2;
}
else {
lua_pushnil(L);
return 1;
}
}
/*
段1
*/
CallInfo是要调用的函数信息,数组形式。这里通过level来算出是第几个CallInfo.
其中一个CallInfo里可能有tailcalls(这是什么还不知道,也算是一种函数调用的优化吧),而
tailcalls是计算到level里面的。比如
0x40 L->ci
0x30 CI(5)
0x20 CI(0)
0x10 CI(0)
..
0x00 L->base_ci, 可能base在这
括号表示tailcalls,这时level为7,取得的是0x10的目标CI,返回base_ci到0x10的偏差
LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
int status;
CallInfo *ci;
lua_lock(L);
/*
L->ci,顶部CallInfo信息
L->base_ci,底部CallInfo信息
*/
for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) {
level--;
if (f_isLua(ci)) /* Lua function? */
level -= ci->tailcalls; /* skip lost tail calls */
}
if (level == 0 && ci > L->base_ci) { /* level found? */
status = 1;
/*
算出目标CallInfo的偏差值
*/
ar->i_ci = cast_int(ci - L->base_ci);
}
else if (level < 0) { /* level is of a lost tail call? */
status = 1;
ar->i_ci = 0;
}
else status = 0; /* no such level */
lua_unlock(L);
return status;
}
/*
段2
*/
lua_getlocal函数的调用关系层如下
lua_getlocal (lua_State *L, const lua_Debug *ar, int n)
{
//根据ar里的偏差值,取到目标ci
CallInfo *ci = L->base_ci + ar->i_ci;
findlocal
Proto *fp = getluaproto(ci);
name = luaF_getlocalname(fp, n, currentpc(L, ci))
}
重点是findlocal的封装。
getluaproto返回函数的属性,先对currentpc展开
static int currentpc (lua_State *L, CallInfo *ci) {
if (!isLua(ci)) return -1; /* function is not a Lua function? */
/*
取的不一定是最末尾的ci
*/
if (ci == L->ci)
ci->savedpc = L->savedpc;
/*
pcRel宏扩展如下,算出ci的执行码和函数的执行码偏差值。中间可以看成塞入了其他
的信息,比如全局变量也会对这个差值造成影响
#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)
*/
return pcRel(ci->savedpc, ci_func(ci)->l.p);
}
来到最后的luaF_getlocalname
const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
int i;
/*
locvars表示存放的函数变量,大小为f->sizelocvars
startpc...endpc,表示在这个范围内的为active变量。
*/
for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) {
if (pc < f->locvars[i].endpc) { /* is variable active? */
local_number--;
if (local_number == 0)
return getstr(f->locvars[i].varname);
}
}
return NULL; /* not found */
}
跟调了下l.p->code和startpc,endpc两个值,在parse的时候就被设置好。
startpc,endpc被设置成l.p->code类似的边界范围值,比如标识局部变量等。
而ci->savedpc和l.p->code之间势必还插入了其他的值,所以你会看到luaF_getlocalname中的判断过程
分享到:
相关推荐
功能应该是对luc反编译的cmd命令(java -jar unluac.jar --rawstring d:\xx.lua>d:\xx.lua)进行了封装 使用时发现反编译出来的汉字未进行解码 用.Net Reflector反编译进行查看,发现程序封装的命令少了--rawstring...
a utf-8 support module for Lua and LuaJIT 源码地址:https://github.com/starwing/luautf8 编译后可用的库: Linux版:lua-utf8.so Windows版:lua-utf8.dll(若是用在openresty中,openresty版本需使用32位版本...
Binary Package lua-devel-5.1.4-4.1.el6.x86_64.rpm Source Package lua-5.1.4-4.1.el6.src.rpm Install HowtoInstall the lua-devel rpm package: ..
llua的源码和php后台源码 ...4.俢改lua中的网站地址和其他数据 说明: 使用rc4加密重要信息,这样不容易被....应该吧 源码还在继续开发中,有什么意见可以评论! 源码可以随意俢改 开发 售卖 反正随便用
1. **src/** 目录:这是主要的源代码存放处,包含了编译Lua解释器(LUA.exe)和编译器(luac.exe)所需的C语言源码。如`lua.c`和`luac.c`是这两个程序的主要实现,`lparser.c`和`llex.c`则涉及到解析和词法分析。 2...
lua-debug.nvim lua-debug.nvim是用于调试正在运行的Neovim实例的适配器。 请参阅以了解有关适配器的更多信息。 它允许您调试Neovim实例中运行的任何lua代码。 免责声明: lua-debug.nvim与具有相似的名称,但与...
4. `Makefile`和`make.bat`:构建脚本,用于编译源码生成lua.exe和luac.exe。 编译方法: 在Windows环境下,你可以使用Visual Studio或MinGW等编译工具来编译Lua源码。通常步骤如下: 1. 打开命令行或终端,进入lua...
支持wireshark解析smgp和sgip协议的lua脚本: 1. 在wireshark安装目录下找到init.lua文件,MAC下位于:/Applications/Wireshark.app/Contents/Resources/share/wireshark 2. 在init.lua同目录下创建sgip.lua和smgp.lua...
分析源码可以揭示Lua是如何实现函数原型、闭包、以及Upvalue机制。 12. 协程及函数的执行: 协程是Lua支持并发的一种机制。源码分析中会看到协程如何在虚拟机中运行,以及如何处理异常、中断和恢复等。 13. ...
2. **lua.h**: 定义了Lua API,包括所有对外暴露的函数和数据结构,是编写Lua C模块时必须包含的头文件。 3. **lualib.h** 和 **luac.h**: 分别包含了标准库和编译器的接口。 4. **lstate.h**: 描述了lua_State...
test pc: ubuntu 14.04 lua : 5.3.0 tools: bash, make demos: 1. test.lua ## hello world 2. function.lua ## 函数调用 3. param.lua ## 函数参数, 4. table ## table ...works/lua_demo$ lua test.lua
- 在IntelliJ IDEA中,设置项目属性,指定lua.exe路径,通常是Lua编译器所在的位置。 - 配置调试配置,包括启动脚本、参数和工作目录,以连接Unity的EmmyLua服务。 6. **测试调试**: - 在Unity中启动调试模式,...
1. `lua.exe`:这是Lua的命令行解释器,允许用户直接在Windows命令提示符下输入和执行Lua代码。通过这个工具,开发者可以快速测试代码片段,或者运行已经编译好的Lua脚本。 2. `lua51.dll`:这是一个动态链接库,...
lua.vm.js Lua VM,在网络上在线演示: : 状态这是作为一个实验来观察Lua VM在网络上运行的速度而开始的。 那是成功的(firefox和chrome的性能都很好)。 下一步是迭代Lua <=> JS互操作性。 正在寻找针对Java语言...
adding: lua5.3.5-x86/lua.exe (in=14336) (out=7311) (deflated 49%) adding: lua5.3.5-x86/lua.o (in=24873) (out=9654) (deflated 61%) adding: lua5.3.5-x86/lua5.3.5-static.lib (in=662596) (out=244441) ...
LuaBitOp和lua-cjson是两个为Lua编程语言编写的扩展库,它们分别提供了位操作和JSON处理的功能。这两个库都是以动态链接库(DLL)的形式存在,可以在Windows环境下与Lua交互。 首先,我们来详细了解LuaBitOp。Lua...
Lua游戏开发实践指南教学.pdf 完整版
《Lua在Nginx中的应用:Lua-Nginx-Module 0.10.9rc7详解》 Lua-Nginx-Module是Nginx服务器中一个强大的扩展模块,允许我们在Nginx配置文件中直接嵌入Lua脚本,极大地提高了Nginx处理动态请求的能力。本文将详细探讨...
`lua-linenoise` 是一个 Lua 语言的库,它是对 `linenoise` 的绑定,`linenoise` 是一个轻量级、高效的命令行历史和补全库,最初由 GitHub 的开发者为 C 语言编写。`lua-linenoise` 的主要目标是将 `linenoise` 的...
内含luaDll,luacom以及luaiconv源码。luaDll和luaiconv直接打开sln在Visual studio中即可进行编译。luacom可使用nmake进行编译。也可直接使用已经生成了的dll.