Lua 是一门小巧精炼的语言,虽然功能不太强大,但是该有的倒也都有,关键是代码量很少,只有不到两万行,非常适合通过阅读代码来学习带虚拟机的脚本语言的实现。本篇以 Lua-5.4.3 的源码为准,参考官方手册。
库函数
Lua 的库函数的源码文件分布基本是按照官方手册索引页给出的分类进行划分的,有了索引页的结构做参照,代码分布就会比较清晰。
- 基础库
基础库就是索引中 base 下面的方法,提供的是最基础的功能,比如加载文件,打印输出这种功能。这部分的代码实现是在 lbaselib.c 中。 - 协程库
索引中 coroutine 下面的部分是 Lua 所有的协程接口,协程是 Lua 中非常重要的组成部分,它们的实现在 lcorolib.c 中。 - 调试库
索引中 debug 下面的部分是 Lua 所有的调试接口,这些接口有时在查 debug 的时候有很好的效果,不过有一些函数运行速度不太好,应该尽量避免在业务逻辑中使用调试库中的函数。调试库的实现是在 ldblia.c 中。 - IO 库
io 下面的函数是 Lua 提供的处理文件输入输出的接口,有两套风格的接口,一套使用隐式的文件句柄,另一套使用显式的文件句柄。IO 库的实现在 liolib.c 中。 - 数学库
math 库提供了一些基础的数学方法,Lua 提供的数学库不算很完善,倒也基本上够用,这部分的代码在 lmathlib.c 中实现。 - os 库
系统库中封装了提供了一些系统接口的封装,平时开发中用的最多的就是时间和日期相关的接口了,系统库的函数在 loslib.c 中实现。 - package 库
package 库提供的是 Lua 的模块加载功能,其中 require 是直接导出到了全局变量中,其它的函数都在 package 表中。package 表中的函数在开发中不怎么常用,实现是在 loadlib.c 中。 - 字符串库
string 库中包含了所有针对字符串操作的函数,库中的函数不仅可以直接调用,同时也被设为了字符串元表的 __index 域,所以也可以通过面向对象的方式调用。这部分的实现在 lstrlib.c 中。 - table 库
table 库中是所有针对 table 的操作,提供的操作其实比较少,不太够用,一般需要自己扩展一下。这部分的实现在 ltablib.c 中。 - utf8 库
utf8 库提供的是对 Unicode 编码数据的支持,除了特殊情况,开发中应该很少用到。这部分的实现在 lutf8lib.c 中。 - C API
由于 Lua 胶水语言的定位,所以提供了很多 C API 供 C/C++ 直接调用。在官方手册中,Index 下所有 C API 下的函数的实现都在 lapi.c 中实现。 - 辅助库
辅助库也就是索引中 auxiliary library 下面的方法,文档中说辅助库是为用户提供一些编写 C 方法时常用的便利函数,相较于 C API 提供的函数来说,辅助库中的函数是 “higher-level functions”,这些函数都是在 lauxlib.c 中实现的。
数据类型
需要有自定义结构的数据类型,它们的结构定义都在 lobject.h 中,还有大量的与数据类型相关的宏方法也在其中。
- 字符串
字符串的结构定义在 lobject.h 中,此外还有 lstring.h 和 lstring.c 两个文件,实现了对字符串的创建等一系列底层操作。 - 函数
Lua 中的函数全部以闭包的形式存在,结构定义在 lobject.h 中,在 lfunc.h 和 lfunc.c 中还有一些针对闭包和函数原型的辅助函数。 - 表
table 除了结构定义在 lobject.h 中以外,其余的逻辑在 ltable.h 和 ltable.c 中,实现了包括 table 创建,修改等一些列操作。
虚拟机
虚拟机的 opcode 部分在 lopcodes.h 和 lopcodes.c 里面定义和实现,VM 中的操作在 lvm.h 和 lvm.c 里面定义和实现,语法解析在 lparser.h 和 lparser.c 里面定义和实现,词法解析在 llex.h 和 llex.c 中定义和实现。
每个进程中有一个 global_state 和很多个 lua_State 变量,这两个的定义和实现在 lstate.h 和 lstate.c 中。
其它
- 保存 chunk
把脚本编译成字节码保存在二进制文件里的实现在 ldump.c 中。 - 初始化库
库的加载方法在 linit.c 中实现。 - 内存分配
内存分配的接口在 lmem.h 和 lmem.c 中。 - GC
GC 方法的定义和实现在 lgc.h 和 lgc.c 中。 - 元方法
元方法相关的内容在 ltm.h 和 ltm.c 中。 - 字符类型
在 lctype.h 和 lctype.c 中实现了一套通过打表快速判断字符类型的方法,比如判断字符是否是空格,是否是数字。这个用在词法解析阶段。