`

LUA源码分析九:Debug."getlocal"

    博客分类:
  • LUA
阅读更多

 

函数:{"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中的判断过程

 

 

1
2
分享到:
评论

相关推荐

    Lua编译与反编译工具.zip

    功能应该是对luc反编译的cmd命令(java -jar unluac.jar --rawstring d:\xx.lua&gt;d:\xx.lua)进行了封装 使用时发现反编译出来的汉字未进行解码 用.Net Reflector反编译进行查看,发现程序封装的命令少了--rawstring...

    lua-utf8.zip

    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位版本...

    lua-5.1.4-4.1.el6.x86_64.rpm

    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: ..

    lua网络验证系统 lua代码 php后台源码下载.zip

    llua的源码和php后台源码 ...4.俢改lua中的网站地址和其他数据 说明: 使用rc4加密重要信息,这样不容易被....应该吧 源码还在继续开发中,有什么意见可以评论! 源码可以随意俢改 开发 售卖 反正随便用

    lua-5.2.2.tar.gz

    1. **src/** 目录:这是主要的源代码存放处,包含了编译Lua解释器(LUA.exe)和编译器(luac.exe)所需的C语言源码。如`lua.c`和`luac.c`是这两个程序的主要实现,`lparser.c`和`llex.c`则涉及到解析和词法分析。 2...

    lua-debug.nvim:Neovim插件的调试适配器

    lua-debug.nvim lua-debug.nvim是用于调试正在运行的Neovim实例的适配器。 请参阅以了解有关适配器的更多信息。 它允许您调试Neovim实例中运行的任何lua代码。 免责声明: lua-debug.nvim与具有相似的名称,但与...

    lua-win-5.3.4源码以及编译后的exe文件和win10环境配置

    4. `Makefile`和`make.bat`:构建脚本,用于编译源码生成lua.exe和luac.exe。 编译方法: 在Windows环境下,你可以使用Visual Studio或MinGW等编译工具来编译Lua源码。通常步骤如下: 1. 打开命令行或终端,进入lua...

    sgip_smgp_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源码分析

    分析源码可以揭示Lua是如何实现函数原型、闭包、以及Upvalue机制。 12. 协程及函数的执行: 协程是Lua支持并发的一种机制。源码分析中会看到协程如何在虚拟机中运行,以及如何处理异常、中断和恢复等。 13. ...

    lua源码下载 Lua-5.3.4 源码 最新 截止2017-3-7

    2. **lua.h**: 定义了Lua API,包括所有对外暴露的函数和数据结构,是编写Lua C模块时必须包含的头文件。 3. **lualib.h** 和 **luac.h**: 分别包含了标准库和编译器的接口。 4. **lstate.h**: 描述了lua_State...

    lua5.3实例

    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

    unity开发lua EmmyLua环境安装.zip

    - 在IntelliJ IDEA中,设置项目属性,指定lua.exe路径,通常是Lua编译器所在的位置。 - 配置调试配置,包括启动脚本、参数和工作目录,以连接Unity的EmmyLua服务。 6. **测试调试**: - 在Unity中启动调试模式,...

    lua51-lua环境

    1. `lua.exe`:这是Lua的命令行解释器,允许用户直接在Windows命令提示符下输入和执行Lua代码。通过这个工具,开发者可以快速测试代码片段,或者运行已经编译好的Lua脚本。 2. `lua51.dll`:这是一个动态链接库,...

    lua.vm.js:该项目由Fengari取代。 参见https:fengari.io

    lua.vm.js Lua VM,在网络上在线演示: : 状态这是作为一个实验来观察Lua VM在网络上运行的速度而开始的。 那是成功的(firefox和chrome的性能都很好)。 下一步是迭代Lua &lt;=&gt; JS互操作性。 正在寻找针对Java语言...

    lua 5.3.5 windows预编译exe/dll文件 lua5.3.5.win.zip

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

    已在window编译的LuaBitOp-1.0.2(bit.dll)和lua-cjson-2.1.0(cjson.dll).zip

    LuaBitOp和lua-cjson是两个为Lua编程语言编写的扩展库,它们分别提供了位操作和JSON处理的功能。这两个库都是以动态链接库(DLL)的形式存在,可以在Windows环境下与Lua交互。 首先,我们来详细了解LuaBitOp。Lua...

    Lua游戏开发实践指南教学.pdf 完整版

    Lua游戏开发实践指南教学.pdf 完整版

    lua-nginx-module-0.10.9rc7

    《Lua在Nginx中的应用:Lua-Nginx-Module 0.10.9rc7详解》 Lua-Nginx-Module是Nginx服务器中一个强大的扩展模块,允许我们在Nginx配置文件中直接嵌入Lua脚本,极大地提高了Nginx处理动态请求的能力。本文将详细探讨...

    lua-linenoise:支持UTF-8的linenoise的Lua绑定(https:github.comyhiroselinenoisetreeutf8-support)

    `lua-linenoise` 是一个 Lua 语言的库,它是对 `linenoise` 的绑定,`linenoise` 是一个轻量级、高效的命令行历史和补全库,最初由 GitHub 的开发者为 C 语言编写。`lua-linenoise` 的主要目标是将 `linenoise` 的...

    luaDll+ luacom+luaiconv.rar

    内含luaDll,luacom以及luaiconv源码。luaDll和luaiconv直接打开sln在Visual studio中即可进行编译。luacom可使用nmake进行编译。也可直接使用已经生成了的dll.

Global site tag (gtag.js) - Google Analytics