Appearance
Lua chunk 文件结构
- header
- prototype
- basic info
- bytecodes
- constants
- upvalues
- debug info
- sub functions
- function1
- function2
- function3
lua
print('hello world')
-- code dump
--[[
hexdump -C luac.out
00000000 1b 4c 75 61 53 00 19 93 0d 0a 1a 0a 04 08 04 08 |.LuaS...........|
00000010 08 78 56 00 00 00 00 00 00 00 00 00 00 00 28 77 |.xV...........(w|
00000020 40 01 0a 40 74 65 73 74 2e 6c 75 61 00 00 00 00 |@..@test.lua....|
00000030 00 00 00 00 00 01 02 04 00 00 00 06 00 40 00 41 |.............@.A|
00000040 40 00 00 24 40 00 01 26 00 80 00 02 00 00 00 04 |@..$@..&........|
00000050 06 70 72 69 6e 74 04 0c 68 65 6c 6c 6f 20 77 6f |.print..hello wo|
00000060 72 6c 64 01 00 00 00 01 00 00 00 00 00 04 00 00 |rld.............|
00000070 00 09 00 00 00 09 00 00 00 09 00 00 00 09 00 00 |................|
00000080 00 00 00 00 00 01 00 00 00 05 5f 45 4e 56 |.........._ENV|
0000008e
--]]
Lua header
Lua 签名
c
/* mark for precompiled code ('<esc>Lua') */
#define LUA_SIGNATURE "\x1bLua"
#define LUAC_VERSION (MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR))
#define LUAC_FORMAT 0 /* this is the official format */
/* data to catch conversion errors */
#define LUAC_DATA "\x19\x93\r\n\x1a\n"
#define LUAC_INT 0x5678
#define LUAC_NUM cast_num(370.5)
/*
** dump Lua function as precompiled chunk
*/
int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data,
int strip) {
DumpState D;
D.L = L;
D.writer = w;
D.data = data;
D.strip = strip;
D.status = 0;
DumpHeader(&D);
DumpByte(f->sizeupvalues, &D);
DumpFunction(f, NULL, &D);
return D.status;
}
// header
static void DumpHeader (DumpState *D) {
DumpLiteral(LUA_SIGNATURE, D);
DumpByte(LUAC_VERSION, D);
DumpByte(LUAC_FORMAT, D);
DumpLiteral(LUAC_DATA, D);
DumpByte(sizeof(int), D); // 04
DumpByte(sizeof(size_t), D); // 08
DumpByte(sizeof(Instruction), D); // 04
DumpByte(sizeof(lua_Integer), D); // 08
DumpByte(sizeof(lua_Number), D); // 08
DumpInteger(LUAC_INT, D); // 22136 => 0x5678
DumpNumber(LUAC_NUM, D); // 0
}
static void DumpFunction (const Proto *f, TString *psource, DumpState *D) {
if (D->strip || f->source == psource)
DumpString(NULL, D); /* no debug info or same source as its parent */
else
DumpString(f->source, D);
DumpInt(f->linedefined, D);
DumpInt(f->lastlinedefined, D);
DumpByte(f->numparams, D);
DumpByte(f->is_vararg, D);
DumpByte(f->maxstacksize, D);
DumpCode(f, D);
DumpConstants(f, D);
DumpUpvalues(f, D);
DumpProtos(f, D);
DumpDebug(f, D);
}