Lua chunk文件结构
1.lua执行经过:
xx.lua源码文件-------》执行(lua虚拟机)
隐式调用luac编译器
我们可以直接用luac命令去编译lua源码文件,然后用编译后的文件运行在lvm(lua虚拟机),具体过程如下:
显示调用luac编译器
2.简要说明
lua编译器是以函数为单位进行编译,每一个函数都会被Lua编译器编译为一个内部结构,这个结构叫“原型”。原型主要包括6个部分:函数基本信息(包括参数数量、局部变量数量等)、字节码、常量表、upvalue表、调试信息、子函数原型列表。由此可知,函数原型是一种递归结构,并且Lua源码中函数的嵌套关系会直接反映在编译后的原型里。
lua编译器会自动为我们的脚步添加一个main函数(即主函数),并且把整个程序都放进这个函数里,然后再以它为起点进行编译,那么自然就把整个程序都编译出来了。这个主函数不仅是编译的起点,也是未来Lua虚拟机解释执行程序时的入口。
如xx.lua源码文件中 就一句代码
print("hello world!")
那么经过Lua编译器加工之后就编程了下面这样:
function main()
print("hello world!")
return
end
3.分析luac编译器编译后的.out文件结构组成(lua5.3版本,每个版本略显不同!具体可参考源码中dump和undump文件)
总体结构图如下:
header头部结构
Java代码头
// chunk头
private static class Header{
private static final byte[] LUA_SIGNATURE = {0x1b, 'L', 'u', 'a'}; // 头 ESC/l/u/a
private static final int LUAC_VERSION = 0x53; // 版本
private static final int LUAC_FORMAT = 0; // 格式
private static final byte[] LUAC_DATA = {0x19, (byte) 0x93, '\r', '\n', 0x1a, '\n'}; // 格式数据
private static final int CINT_SIZE = 4; // cint占字节数
private static final int CSIZET_SIZE = 8; // size_t占字节数
private static final int INSTRUCTION_SIZE = 4; //Lua指令占字节数
private static final int LUA_INTEGER_SIZE = 8; //Lua整数占字节数
private static final int LUA_NUMBER_SIZE = 8; // Lua浮点数占字节数
private static final int LUAC_INT = 0x5678; // 测试字节大小端
private static final double LUAC_NUM = 370.5; // 测试浮点数
}