`
eric_weitm
  • 浏览: 243717 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

lua 源代码解析

阅读更多
lua 源代码解析

源代码版本:lua-5.2.0
一、概览
1、lua脚本中暴露的库相关
lbaselib.c - 基础函数库(方便使用lua内部的功能)
lbitlib.c - 位运算库
lcorolib.c - 协程库
lstrlib.c - 字符串库,提供通用字符串处理功能
  lstring.c - 字符串表(保存所有由Lua操作的字符串集合)
lmathlib.c - 数学库
loslib.c - 操作系统相关库,时间、环境、语言、执行程序等
liolib.c - 输入输出库
loadlib.c - 模块库(实现require函数,package函数)
ldblib.c - 调试库
  ldebug.c - 调试接口:包含访问调试钩子的函数(lua_sethook/lua_gethook/lua_gethookcount),访问运行时堆栈信息的函数(lua_getstatck/lua_getlocal/lua_setlocal),检查字节码函数(luaG_checkopenop/luaG_checkcode),和抛出错误的函数(luaG_typeerror/luaG_concaterror/luaG_aritherror/luaG_ordererror/luaG_errormsg/luaG_runerror)
lapi.c - Lua的API.实现Lua C API(lua_*函数)集合
lauxlib.c - 定义所有的luaL_*函数集

2、lua runtime的数据结构相关
lfunc.c - 包装原型和闭包的辅助函数
ltable.c - Lua表实现(哈希)
lobject.c - 一些针对Lua对象的通用函数。包括数据类型到字符串转换函数,纯数据相等测试函数(luaO_rawequalObj),和日志基础2(luaO_log2)
ltm.c - 标记原语方法。实现对象访问原语方法(metathods)

3、编译前端
llex.c - 词法分析器,被lparser.c使用,接口LUAI_FUNC void luaX_next (LexState *ls);
lparser.c - Lua语法检查器,接口 Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, Dyndata *dyd, const char *name, int firstchar);
lundump.c - 加载预编译后的Lua代码块,函数luaU_undump,加载一个预编译后的代码块;luaU_header(被luaU_undump使用的内部函数),用来检查函数头部。
ldump.c - 保存预编译后的Lua代码块。函数luaU_dump,使用预编译后的代码字符串展示一个函数;
lcode.c - Lua的代码生成器。被lparser.c使用,static int luaK_code (FuncState *fs, Instruction i) 用于写入一条指令
  顺序:lex--parse--code--dump

4、虚拟机、运行时相关
lopcodes.c - Lua虚拟机的操作码。定义所有操作符的名称和信息(使用luaP_opnames和luaP_opmodes两个表保存)
lvm.c - Lua虚拟机。执行字节码(luaV_execute)。也暴漏一些lapi.c可能用到的函数(例如:luaV_concat)
ldo.c - Lua的栈和调用结构。控制函数调用(luaD_call/luaD_pcall),栈增长,协同代码的同步
lstate.c - 全局上下文信息即 符号表(函数表、变量表、线程等). 包括打开和关闭LUA上线文的函数(lua_newstate/lua_close)和lua线程函数(luaE_newthread/luaE_freethread)
lmem.c - 内存管理的接口.通过封装内存分配函数,实现了luaM_realloc / luaM_growaux_两个函数.
lgc.c -  垃圾回收器(内存管理)

5、外部封装
lua.c - Lua独立解释器
luac.c - Lua编译器(保存字节码到一个文件,也可以列出字节码)

6、其他
lzio.c -  一个通用的带缓冲区的输入流接口
linit.c - 实现luaL_openlibs方法,便于在C语言中加载上述模块
lctype.c 判断类型

二、主流程
第一阶段:main---load----词法、语法解析、parser内会生成需要的指令集
第二阶段:docall----虚拟机内的luaV_execute

三、runtime的实现
  1、vc中的一个典型调用栈信息如下:
> lua1.exe!luaV_execute(lua_State * L=0x00035c28)  Line 521 C
lua1.exe!luaD_call(lua_State * L=0x00035c28, lua_TValue * func=0x00035e00, int nResults=-1, int allowyield=0)  Line 393 + 0x9 bytes C
lua1.exe!f_call(lua_State * L=0x00035c28, void * ud=0x0013f4a0)  Line 920 + 0x18 bytes C
lua1.exe!luaD_rawrunprotected(lua_State * L=0x00035c28, void (lua_State *, void *)* f=0x00424a60, void * ud=0x0013f4a0)  Line 133 + 0x1f bytes C
lua1.exe!luaD_pcall(lua_State * L=0x00035c28, void (lua_State *, void *)* func=0x00424a60, void * u=0x0013f4a0, int old_top=40, int ef=32)  Line 591 + 0x11 bytes C
lua1.exe!lua_pcallk(lua_State * L=0x00035c28, int nargs=0, int nresults=-1, int errfunc=3, int ctx=0, int (lua_State *)* k=0x00000000)  Line 946 + 0x20 bytes C
lua1.exe!docall(lua_State * L=0x00035c28, int narg=0, int nres=-1)  Line 179 + 0x19 bytes C
lua1.exe!handle_script(lua_State * L=0x00035c28, char * * argv=0x00035ba0, int n=1)  Line 341 + 0xf bytes C
lua1.exe!pmain(lua_State * L=0x00035c28)  Line 469 + 0x17 bytes C
lua1.exe!luaD_precall(lua_State * L=0x00035c28, lua_TValue * func=0x00035de0, int nresults=1)  Line 317 + 0x9 bytes C
lua1.exe!luaD_call(lua_State * L=0x00035c28, lua_TValue * func=0x00035de0, int nResults=1, int allowyield=0)  Line 392 + 0x11 bytes C
lua1.exe!f_call(lua_State * L=0x00035c28, void * ud=0x0013fe48)  Line 920 + 0x18 bytes C
lua1.exe!luaD_rawrunprotected(lua_State * L=0x00035c28, void (lua_State *, void *)* f=0x00424a60, void * ud=0x0013fe48)  Line 133 + 0x1f bytes C
lua1.exe!luaD_pcall(lua_State * L=0x00035c28, void (lua_State *, void *)* func=0x00424a60, void * u=0x0013fe48, int old_top=8, int ef=0)  Line 591 + 0x11 bytes C
lua1.exe!lua_pcallk(lua_State * L=0x00035c28, int nargs=2, int nresults=1, int errfunc=0, int ctx=0, int (lua_State *)* k=0x00000000)  Line 946 + 0x20 bytes C
lua1.exe!main(int argc=2, char * * argv=0x00035ba0)  Line 495 + 0x13 bytes C

  2、基本交互逻辑
  vm循环取出一个一个的Instruction,之后一个巨大的switch来解释这个Instruction(lua 5.2是基于寄存器的指令集),即经典的fetch---execute循环。
特殊的指令:
1》函数调用指令:遇到函数调用时(lua中调用),要用c代码模拟出硬件执行代码时的栈结构。
基本上每次增加一个活动记录时要设置好相应的闭包信息和执行环境,设置好相应的符号表,做好参数的检查,必要时GC一下
2》协程指令   :每次有create调用时就新建一个lua_state,全局栈维护这些stack信息
  resume时 luaB_coresume---auxresume---lua_resume---luaB_yield
   lua1.exe!lua_yieldk(lua_State * L=0x0003e698, int nresults=1, int ctx=0, int (lua_State *)* k=0x00000000)  Line 556 C
lua1.exe!luaB_yield(lua_State * L=0x0003e698)  Line 99 + 0x1a bytes C
lua1.exe!luaD_precall(lua_State * L=0x0003e698, lua_TValue * func=0x0003f3f8, int nresults=-1)  Line 317 + 0x9 bytes C
lua1.exe!luaV_execute(lua_State * L=0x0003e698)  Line 744 + 0x34 bytes C
lua1.exe!resume(lua_State * L=0x0003e698, void * ud=0x0003f3d8)  Line 496 + 0x9 bytes C
lua1.exe!luaD_rawrunprotected(lua_State * L=0x0003e698, void (lua_State *, void *)* f=0x004348d0, void * ud=0x0003f3d8)  Line 133 + 0x1f bytes C
lua1.exe!lua_resume(lua_State * L=0x0003e698, lua_State * from=0x00035c28, int nargs=2)  Line 531 + 0x1d bytes C
> lua1.exe!auxresume(lua_State * L=0x00035c28, lua_State * co=0x0003e698, int narg=2)  Line 31 + 0x11 bytes C
lua1.exe!luaB_coresume(lua_State * L=0x00035c28)  Line 53 + 0x1d bytes C


四、解释器
1、main函数
line484: lua.c
lua_newstate:全局和线程栈状态的初始化

lua_State *L = luaL_newstate();  // 创建全局的运行时信息
lua_pushcfunction(L, &pmain);    // 创建当前栈顶的函数闭包


lua_pushinteger(L, argc);  // 参数入栈
lua_pushlightuserdata(L, argv); /* 2nd argument */
status = lua_pcall(L, 2, 1, 0); // 运行时执行一个lua函数
result = lua_toboolean(L, -1);  /* get result */
finalreport(L, status);
lua_close(L);               // 释放内存等扫尾工作

2、lua_pcall详情
1》参数检查
2》luaD_pcall --------luaD_rawrunprotected---f_call----luaD_call---luaD_precall---pmain

luaL_checkversion(L); // 验证虚拟机
lua_gc(L, LUA_GCSTOP, 0);  /* stop collector during initialization */
luaL_openlibs(L);     // 初始化内置库 loadedlibs是默认打开的功能表
lua_gc(L, LUA_GCRESTART, 0);

handle_script -------执行主脚本

luaL_loadfile------docall(一堆的栈操作)----luaV_execute:lvm.c // 虚拟机的执行引擎
分享到:
评论

相关推荐

    Lua源代码分析顺序

    ### Lua源代码分析顺序 #### 一、概览 在深入了解Lua源代码的过程中,遵循一定的阅读顺序至关重要。本文旨在提供一份详细的指南,帮助读者更好地理解Lua的内部实现机制及其核心功能。通过按照推荐的顺序阅读相关...

    lua的源代码

    9. **字节码编译和反编译**:`luac.c`包含了一个编译器,将Lua源代码编译成字节码,方便快速执行。同时,`luac.out`包含反编译功能,能将字节码转回源码形式,便于理解和调试。 10. **错误处理和调试**:Lua源代码...

    介于许多小伙伴 打开lua官网很慢,下载lua源代码很慢,传一个lua5.4.6最新版本的源代码

    Lua源代码还包含一些头文件,如`lua.h`,定义了C API,以及`luaconf.h`,用于配置编译选项。开发者可以根据需要自定义这些配置,以适应特定平台或需求。 对于初学者,可以通过阅读和分析源代码来深入理解Lua的工作...

    lua源代码可跨平台移植

    标题“lua源代码可跨平台移植”揭示了Lua语言的一个核心特性,即它的源代码可以在多种操作系统上编译和运行,包括但不限于Windows、Linux、Mac OS X、Android以及iOS等。这种跨平台能力使得开发者能够在不同的硬件和...

    LUA源代码-扫雷游戏

    总结来说,通过分析这个“LUA源代码-扫雷游戏”,我们可以学习到LUA语言的基本语法、数据结构、函数和控制流,以及如何利用LUA进行事件处理和图形界面编程。这对于想要深入理解LUA或游戏开发的初学者来说是一份很好...

    MarpaX-Languages-Lua-Parser:Lua源代码解析器-lua source code

    MarpaX-Languages-Lua-Parser:Lua源代码解析器

    lua 语言源代码

    深入研究Lua源代码,我们可以学习到其如何实现这些特性,包括词法分析、语法解析、虚拟机设计、内存管理等方面的知识。通过阅读和理解源代码,开发者不仅可以提升对Lua语言的理解,还能学习到一些底层编程技巧和优化...

    LUAC反编译_LUC_lua反编译工具_luac_luac解密工具_Lua解密_

    首先,LUAC编译器的工作原理是将Lua源代码解析成抽象语法树(AST),然后将其转化为二进制的字节码。这个字节码不是人类可读的,但仍然可以通过Lua虚拟机(VM)执行。LUAC编译的字节码文件通常以".luac"为扩展名。 ...

    decoda lua源代码

    Decoda是一款强大的Lua源代码调试工具,主要用于32位Lua程序的联合调试。在本文中,我们将深入探讨Decoda的功能、工作原理以及如何利用它来优化32位Lua程序的开发流程。 首先,让我们理解什么是Lua。Lua是一种轻量...

    LUA5.0 源代码

    通过分析这些代码,我们可以理解LUA如何将源代码转换为高效的字节码,以及字节码如何被解析和执行。 2. **数据结构**:LUA5.0使用了一些高效的数据结构,如表(table)作为通用的关联数组,它结合了哈希和动态数组...

    bstree:Lua 源代码混淆器

    它分析源代码中的 Lua 文件并输出编码器和解码器。 BS 代表 Bit Stream 或 Bull Shit,取决于你的心情。 用法 $ lua bstree.lua <input.lua>+ 此命令将分析所有给定的 Lua 文件并输出两个文件: bsenc.lua...

    lua 源代码 添加了 cJson

    在这个“lua 源代码 添加了 cJson”的项目中,开发者整合了Luaj,一个允许Java应用程序运行Lua脚本的库,与cJson,一个高效的C语言实现的JSON解析器和序列化器。这样的结合对于Android应用尤其有用,因为它可以在...

    lua源代码--老虎吃绵羊

    【lua源代码--老虎吃绵羊】 Lua是一种轻量级的、高级的、可扩展的脚本语言,常用于游戏开发、嵌入式系统以及各种应用程序。在这个项目中,“老虎吃绵羊”是一个使用Lua编写的简单游戏或者模拟程序,可能是为了演示...

    c++读取lua配置文件的源代码

    这通常涉及下载Lua源代码,编译为静态或动态库,并在C++项目中链接。确保你正确地配置了头文件路径和库路径,以便在C++代码中包含所需的`#include`s。 接下来,我们关注`LuaConfigReader.cpp`和`LuaConfigReader.h`...

    Lua调试工具及源代码

    通过分析和学习它的源代码,你可以深入了解Lua的运行机制,掌握如何在C++中实现一个调试器,并学习如何与Lua交互。这将对提升你的Lua编程技能和理解调试工具的工作原理大有裨益。同时,源代码的开放性也鼓励了社区的...

    LUA进阶源代码欣赏

    "LUA进阶源代码欣赏"是一个面向LUA初学者和有一定经验的开发者的学习资源,旨在通过分析和解读源代码,提升对LUA语言深入理解和应用的能力。 1. **函数与表** LUA中的函数是一等公民,可以作为变量存储、作为参数...

    lua:lua源代码测试-lua source code

    "lua:lua源代码测试-lua source code"这个主题,显然关注的是对Lua语言核心源码的学习与测试。 在深入探讨之前,我们先了解一些基础概念。Lua语言的设计目标是简洁、可嵌入和可扩展。它由C语言编写,具有小巧的运行...

    LuaMinify:Lua源代码压缩器-lua source code

    主要是Lua源代码压缩程序,但还包括一些静态分析工具以及通用的Lua词法分析器和解析器。 当前,minifier执行: 剥离所有注释和空格 将所有局部变量真正语义重命名为简化形式 将源减少到最小间距,仅在实际需要的...

    LUA语言解析器

    通过编译`luac.c`,我们可以得到一个名为`luac`的可执行程序,这个程序能够读取LUA源代码并生成对应的预编译字节码文件,通常以`.lua`后缀命名。预编译字节码有助于提高程序的加载速度,因为它避免了运行时的解释...

    lua编译&反编译,lua反编译工具,Java

    编译的主要目的是为了提高程序的加载速度,因为字节码可以直接被解释器执行,避免了源代码解析的开销。 反编译是将已编译的Lua字节码文件转换回源代码的过程。这通常用于分析或调试已经编译的代码,或者在源代码...

Global site tag (gtag.js) - Google Analytics