Lua/LuaJIT 字节码浅析
                                                      清无
                                              2012-05-29


Contents
1 外部存 格式                                                                                                                                              1
  1.1 Lua 5.1 字节码外部结构 . . .                   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   1
  1.2 Lua 5.1 字节码实例分析 . . .                   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   3
  1.3 LuaJIT 2.0 函数原型内存结构                     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   5
  1.4 LuaJIT 2.0 字节码外部结构 .                    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   5
  1.5 LuaJIT 2.0 字节码实例分析 .                    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   6

2 Closure Factory 包 代码实现                                                                                                                              7
  2.1 Lua 5.1 下的实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                                                                  7
  2.2 LuaJIT 2.0 下的实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                                                                   8

3 字节码参考                                                                                                                                                9
  3.1 Lua 5.1   字节码种类 . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    9
  3.2 Lua 5.1   字节码列表 . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    9
  3.3 LuaJIT    2.0 字节码种类         .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    9
  3.4 LuaJIT    2.0 字节码列表         .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   10




1    外部存          格式
1.1 Lua 5.1 字节码外部结构
    参考 luaU_dump@ldump.c

    • header 结构




                                                          1
1.1 Lua 5.1 字节码外部结构                  1   外部存 格式




  • 基本数据类型外部结构




 注意 Lua 5.1 的内部字符串末尾总会自动添加一个 ‘’,在外部表示法中该字符将一并输
出。

  • 函数外部结构 (即输出 Proto 对象时的结构)




                         2
1.2 Lua 5.1 字节码实例分析                                   1   外部存 格式




    • luac 同时给定多文件时是打包编译,其处理方式是创建一个新的匿名函数,将每个文
      件内的代码作为该函数的一个内部函数处理,   匿名函数顺序调用这些内部函数运行

    • 标准 Lua 5.1 的字节码文件不可跨平台使用,        因为其使用了 int/size_t/lua_Number
      等不同平台不同编译选项下字长都不一样的类型,             若在不兼容编译的 Lua 中加载将
      因为 header 不匹配而报告 “bad header” 错误

1.2 Lua 5.1 字节码实例分析
    示例代码为:
§                                                                     ¤
    1 return function()
    2     print "hello"
    3 end
¦                                                                     ¥
通过 luac 编译后字节码文件内容分析如下:




                                 3
1.2 Lua 5.1 字节码实例分析                                                    1   外部存 格式


     字节序列                            含
                                     header
     1b 4c 75 61                     LUA_SIGNATURE: “(esc)Lua”
     51                              LUAC_VERSION (5.1)
     00                              LUAC_FORMAT (official binary file)
     01                              little endian
     04                              LP64 linux: sizeof(int)==4
     08                              LP64 linux: sizeof(size_t)==8
     04                              LP64 linux: sizeof(Instruction)==4
     08                              lua_Number is double: sizeof(lua_Number)==8
     00                              lua_Number is some kind of float
                                     function 0 begins
     08   00   00   00 00 00 00 00   function 0 source str len
     40   61   31   2e 6c 75 61 00   function 0 source str: “@a1.lua(nil)”
     00   00   00   00               function 0 linedefined
     00   00   00   00               function 0 lastlinedefined
     00                              function 0 upvalues
     00                              function 0 numparams
     02                              function 0 is vararg func
     02                              function 0 maxstacksize
     03   00 00 00                   function 0 bytecode instruction num
                                     function 0 bytecode begins
     24 00 00 00                     CLOSURE 0 0
     1e 00 00 01                     RETURN 0 2
     1e 00 80 00                     RETURN 0 1
     00 00 00 00                     function 0 referenced consts
     01 00 00 00                     number of internal functions in function 0
                                     function 1 inserted
     00   00 00 00 00 00 00 00       function 1 source str len
     01   00 00 00                   function 1 linedefined
     03   00 00 00                   function 1 lastlinedefined
     00                              function 1 upvalues
     00                              function 1 numparams
     00                              function 1 is normal func
     02                              function 1 maxstacksize
     04   00 00 00                   function 1 bytecode instruction num
                                     function 1 bytecode begins
     05 00 00 00                     GETGLOBAL 0 0
     41 40 00 00                     LOADK 1 1
     1c 40 00 01                     CALL 0 2 1
     1e 00 80 00                     RETURN 0 1




                                              4
1.3 LuaJIT 2.0 函数原型内存结构                                                 1   外部存 格式


        字节序列                        含
                                    function 1 consts begins
        02   00 00 00               function 1 referenced consts
        04                          const 0 type: LUA_TSTRING(4)
        06   00 00 00 00 00 00 00   const 0 length
        70   72 69 6e 74 00         const 0 content: “print(nil)”
        04                          const 1 type: LUA_TSTRING(4)
        06   00 00 00 00 00 00 00   const 1 length
        68   65 6c 6c 6f 00         const 1 content: “hello(nil)”
        00   00 00 00               number of internal functions in function 1
                                    function 1 debug info begins
        04   00   00   00           function 1 lineinfo vector size
        02   00   00   00           src lineno of bytecode 0
        02   00   00   00           src lineno of bytecode 1
        02   00   00   00           src lineno of bytecode 2
        03   00   00   00           src lineno of bytecode 3
        00   00   00   00           number of local vars in function 1
        00   00   00   00           number of upvalues in function 1
                                    function 0 resumed
                                    function 0 debug info begins
        03   00   00   00           function 0 lineinfo vector size
        03   00   00   00           src lineno of bytecode 0
        03   00   00   00           src lineno of bytecode 1
        03   00   00   00           src lineno of bytecode 2
        00   00   00   00           number of local vars in function 0
        00   00   00   00           number of upvalues in function 0

1.3 LuaJIT 2.0 函数原型内存结构




1.4 LuaJIT 2.0 字节码外部结构
  参考 lj_bcwrite@lj_bcwrite.c

  • header 结构

                                           5
1.5 LuaJIT 2.0 字节码实例分析                             1   外部存 格式




    • 函数外部结构 (即输出 GCproto 对象时的结构)




    • footer 结构:在文件末尾附加单字节 0

    • LuaJIT 2.0 字节码文件可跨平台使用,        因为其只使用了字节、  ULEB128 变长序列化方
      案和定长整数。但其格式可能在不同 major/minor 版本间变化,          加载不同版本的字节
      码时会报告 cannot load incompatible bytecode 错误

1.5 LuaJIT 2.0 字节码实例分析
    示例代码为:
§                                                                 ¤
    1 return function()
    2     print "hello"
    3 end
¦                                                                 ¥
通过 luajit -b 编译后字节码文件内容分析如下:




                               6
2 CLOSURE FACTORY 包 代码实现


          字节序列              含
                            header
             1b 4c 4a       BCDUMP_HEAD1/2/3: “(esc)LJ”
                   01       BCDUMP_VERSION
                   02       flag: no FFI, stripped, little endian
                            function 0 begins
                       23   function 0 rest data total length: 35
                       00   function 0 flag: no ffi, no vararg, no child
                       00   function 0 parameters
                       00   function 0 framesize
                       00   function 0 upvalues number
                       02   function 0 collectable consts number
                       00   function 0 lua_number consts number
                       04   function 0 bytecode number
                            function 0 bytecode begins
        34   00   00   00   GGET 0 0
        25   01   01   00   KSTR 1 1
        3e   00   02   01   CALL 0 1 2
        47   00   01   00   RET0 0 1
                            function 0 gc’able consts begins
                 0a         gc’able const 0 type (type=bcdump_kgc_str(5), len=10-5=5)
      68 65 6c 6c 6f        gc’able const 0 content: “hello”
                 0a         gc’able const 1 type (type=bcdump_kgc_str(5), len=10-5=5)
     70 72 69 6e 74         gc’able const 1 content: “print”
                            function 1 begins
                       14   function 1 rest data total length: 20
                       03   function 1 flag: no FFI, vararg, has child
                       00   function 1 parameters
                       01   function 1 framesize
                       00   function 1 upvalues number
                       01   function 1 collectable consts number
                       00   function 1 lua_number consts number
                       03   function 1 bytecode number
                            function 1 bytecode begins
        31 00 00 00         FNEW 0 0
        30 00 00 80         UCLO 0 0
        48 00 02 00         RET1 0 2
                            function 1 gc’able consts begins
                       00   gc’able const 0 type (type=BCDUMP_KGC_CHILD(0))
                            footer
                       00   bytecode file footer


2 Closure Factory 包                        代码实现
2.1 Lua 5.1 下的实现
  对于 Lua 5.1,    需要识别待加载字节码 header 中的 int、        size_t、Instruction 字长,相应构
建 closure factory 函数字节码, 并将原用户字节码的函数部分整体作为 closure factory 函数
的内部函数插入。例如,          对于 int、size_t、Instruction 字长分别为 4、 4 的 Lua 平台下编译
                                                          8、


                                                7
2.2 LuaJIT 2.0 下的实现                      2 CLOSURE FACTORY 包 代码实现


出的用户字节码,构造 closure factory 的方法为:
 1. 读入待加载字节码 header 并原样输出

 2. 读取待加载字节码 body 数据中的 8(size_t) 字节长度,按此长度读出后续的 source
    字符串内容,并将长度和字符串内容输出

 3. 输出 int 字长的空 linedefined 字段: 0x00 0x00 0x00 0x00

 4. 输出 int 字长的空 lastlinedefined 字段: 0x00 0x00 0x00 0x00

 5. 输出 char 字长的空 nups 字段: 0x00

 6. 输出 char 字长的空 numparams 字段: 0x00

 7. 输出 char 字长的 is_vararg 字段值 2 表示 main chunk 为变参函数: 0x02

 8. 输出 char 字长的 maxstacksize 默认值 2: 0x02

 9. 输出 int 字长的 closure factory 函数字节码长度 3: 0x03 0x00 0x00 0x00

 10. 输出 Instruction 字长的 3 条 closure factory 函数字节码: 0x24 0x00 0x00 0x00 0x1e
     0x00 0x00 0x01 0x1e 0x00 0x80 0x00

 11. 输出 int 字长的空 sizek 字段: 0x00 0x00 0x00 0x00

 12. 输出 int 字长的 sizep 字段值 1, 以便将原用户字节码作为 closure factory 的内部函数
     处理: 0x01 0x00 0x00 0x00

 13. 插入待加载字节码 body 数据

 14. 输出 int 字长的空 sizelineinfo 字段:0x00 0x00 0x00 0x00

 15. 输出 int 字长的空 sizelocvars 字段:0x00 0x00 0x00 0x00

 16. 输出 int 字长的空 sizeupvalues 字段:0x00 0x00 0x00 0x00

 17. 完成!

2.2 LuaJIT 2.0 下的实现
    LuaJIT 2.0 的字节码是平台无关的,   且父函数总在其子函数之后输出,故添加 closure
factory 时比 Lua 5.1 简单的多,方法为:
 1. 读入全部待加载字节码数据,截去末尾 footer 的 1 字节后原样输出

 2. 输出 ULEB128 编码方式的 closure factory 函数剩余数据长度 20: 0x14

 3. 输出 closure factory 函数标志字节 (no ffi, vararg, has child): 0x03

 4. 输出 char 字长的空 numparams 字段:0x00

 5. 输出 char 字长的默认 framesize 字段:0x01

 6. 输出 char 字长的空 nups 字段:0x00

 7. 输出 ULEB128 编码方式的可回收常量计数 1,因为 closure factory 仅引用目标字节
    码这一常量:0x01

                                     8
3 字节码参考


    8. 输出 ULEB128 编码方式的数值常量计数 0:0x00

    9. 输出 ULEB128 编码方式的 closure factory 字节码数量 3:0x03

10. 输出 int32_t 字长的 3 条 closure factory 字节码:0x31 0x00 0x00 0x00 0x30 0x00
    0x00 0x80 0x48 0x00 0x02 0x00

11. 输出含有目标字节码占位空间的可回收常量区:0x00

12. 输出末尾 footer:0x00

13. 完成!


3    字节码参考
3.1 Lua 5.1 字节码种类
    参考 lopcodes.h




3.2 Lua 5.1 字节码列表
                       符      OPCODE 参数 式           能
                    LOADK         0x01 iABx
                    GETGLOBAL     0x05 iABx
                    CALL          0x1c iABC
                    RETURN        0x1e iABC
                    CLOSURE       0x24 iABx

3.3 LuaJIT 2.0 字节码种类
    参考 lj_bc.h




                                  9
3.4 LuaJIT 2.0 字节码列表                          3 字节码参考




3.4 LuaJIT 2.0 字节码列表
                    符   OPCODE     参数 式   能
                 KSTR       0x25   AD
                 UCLO       0x30   AD
                 FNEW       0x31   AD
                 GGET       0x34   AD
                 CALL       0x3e   ABC
                 RET0       0x47   AD
                 RET1       0x48   AD




                              10

Lua/LuaJIT 字节码浅析

  • 1.
    Lua/LuaJIT 字节码浅析 清无 2012-05-29 Contents 1 外部存 格式 1 1.1 Lua 5.1 字节码外部结构 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.2 Lua 5.1 字节码实例分析 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.3 LuaJIT 2.0 函数原型内存结构 . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.4 LuaJIT 2.0 字节码外部结构 . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.5 LuaJIT 2.0 字节码实例分析 . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 2 Closure Factory 包 代码实现 7 2.1 Lua 5.1 下的实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 2.2 LuaJIT 2.0 下的实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 3 字节码参考 9 3.1 Lua 5.1 字节码种类 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 3.2 Lua 5.1 字节码列表 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 3.3 LuaJIT 2.0 字节码种类 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 3.4 LuaJIT 2.0 字节码列表 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 1 外部存 格式 1.1 Lua 5.1 字节码外部结构 参考 luaU_dump@ldump.c • header 结构 1
  • 2.
    1.1 Lua 5.1字节码外部结构 1 外部存 格式 • 基本数据类型外部结构 注意 Lua 5.1 的内部字符串末尾总会自动添加一个 ‘’,在外部表示法中该字符将一并输 出。 • 函数外部结构 (即输出 Proto 对象时的结构) 2
  • 3.
    1.2 Lua 5.1字节码实例分析 1 外部存 格式 • luac 同时给定多文件时是打包编译,其处理方式是创建一个新的匿名函数,将每个文 件内的代码作为该函数的一个内部函数处理, 匿名函数顺序调用这些内部函数运行 • 标准 Lua 5.1 的字节码文件不可跨平台使用, 因为其使用了 int/size_t/lua_Number 等不同平台不同编译选项下字长都不一样的类型, 若在不兼容编译的 Lua 中加载将 因为 header 不匹配而报告 “bad header” 错误 1.2 Lua 5.1 字节码实例分析 示例代码为: § ¤ 1 return function() 2 print "hello" 3 end ¦ ¥ 通过 luac 编译后字节码文件内容分析如下: 3
  • 4.
    1.2 Lua 5.1字节码实例分析 1 外部存 格式 字节序列 含 header 1b 4c 75 61 LUA_SIGNATURE: “(esc)Lua” 51 LUAC_VERSION (5.1) 00 LUAC_FORMAT (official binary file) 01 little endian 04 LP64 linux: sizeof(int)==4 08 LP64 linux: sizeof(size_t)==8 04 LP64 linux: sizeof(Instruction)==4 08 lua_Number is double: sizeof(lua_Number)==8 00 lua_Number is some kind of float function 0 begins 08 00 00 00 00 00 00 00 function 0 source str len 40 61 31 2e 6c 75 61 00 function 0 source str: “@a1.lua(nil)” 00 00 00 00 function 0 linedefined 00 00 00 00 function 0 lastlinedefined 00 function 0 upvalues 00 function 0 numparams 02 function 0 is vararg func 02 function 0 maxstacksize 03 00 00 00 function 0 bytecode instruction num function 0 bytecode begins 24 00 00 00 CLOSURE 0 0 1e 00 00 01 RETURN 0 2 1e 00 80 00 RETURN 0 1 00 00 00 00 function 0 referenced consts 01 00 00 00 number of internal functions in function 0 function 1 inserted 00 00 00 00 00 00 00 00 function 1 source str len 01 00 00 00 function 1 linedefined 03 00 00 00 function 1 lastlinedefined 00 function 1 upvalues 00 function 1 numparams 00 function 1 is normal func 02 function 1 maxstacksize 04 00 00 00 function 1 bytecode instruction num function 1 bytecode begins 05 00 00 00 GETGLOBAL 0 0 41 40 00 00 LOADK 1 1 1c 40 00 01 CALL 0 2 1 1e 00 80 00 RETURN 0 1 4
  • 5.
    1.3 LuaJIT 2.0函数原型内存结构 1 外部存 格式 字节序列 含 function 1 consts begins 02 00 00 00 function 1 referenced consts 04 const 0 type: LUA_TSTRING(4) 06 00 00 00 00 00 00 00 const 0 length 70 72 69 6e 74 00 const 0 content: “print(nil)” 04 const 1 type: LUA_TSTRING(4) 06 00 00 00 00 00 00 00 const 1 length 68 65 6c 6c 6f 00 const 1 content: “hello(nil)” 00 00 00 00 number of internal functions in function 1 function 1 debug info begins 04 00 00 00 function 1 lineinfo vector size 02 00 00 00 src lineno of bytecode 0 02 00 00 00 src lineno of bytecode 1 02 00 00 00 src lineno of bytecode 2 03 00 00 00 src lineno of bytecode 3 00 00 00 00 number of local vars in function 1 00 00 00 00 number of upvalues in function 1 function 0 resumed function 0 debug info begins 03 00 00 00 function 0 lineinfo vector size 03 00 00 00 src lineno of bytecode 0 03 00 00 00 src lineno of bytecode 1 03 00 00 00 src lineno of bytecode 2 00 00 00 00 number of local vars in function 0 00 00 00 00 number of upvalues in function 0 1.3 LuaJIT 2.0 函数原型内存结构 1.4 LuaJIT 2.0 字节码外部结构 参考 lj_bcwrite@lj_bcwrite.c • header 结构 5
  • 6.
    1.5 LuaJIT 2.0字节码实例分析 1 外部存 格式 • 函数外部结构 (即输出 GCproto 对象时的结构) • footer 结构:在文件末尾附加单字节 0 • LuaJIT 2.0 字节码文件可跨平台使用, 因为其只使用了字节、 ULEB128 变长序列化方 案和定长整数。但其格式可能在不同 major/minor 版本间变化, 加载不同版本的字节 码时会报告 cannot load incompatible bytecode 错误 1.5 LuaJIT 2.0 字节码实例分析 示例代码为: § ¤ 1 return function() 2 print "hello" 3 end ¦ ¥ 通过 luajit -b 编译后字节码文件内容分析如下: 6
  • 7.
    2 CLOSURE FACTORY包 代码实现 字节序列 含 header 1b 4c 4a BCDUMP_HEAD1/2/3: “(esc)LJ” 01 BCDUMP_VERSION 02 flag: no FFI, stripped, little endian function 0 begins 23 function 0 rest data total length: 35 00 function 0 flag: no ffi, no vararg, no child 00 function 0 parameters 00 function 0 framesize 00 function 0 upvalues number 02 function 0 collectable consts number 00 function 0 lua_number consts number 04 function 0 bytecode number function 0 bytecode begins 34 00 00 00 GGET 0 0 25 01 01 00 KSTR 1 1 3e 00 02 01 CALL 0 1 2 47 00 01 00 RET0 0 1 function 0 gc’able consts begins 0a gc’able const 0 type (type=bcdump_kgc_str(5), len=10-5=5) 68 65 6c 6c 6f gc’able const 0 content: “hello” 0a gc’able const 1 type (type=bcdump_kgc_str(5), len=10-5=5) 70 72 69 6e 74 gc’able const 1 content: “print” function 1 begins 14 function 1 rest data total length: 20 03 function 1 flag: no FFI, vararg, has child 00 function 1 parameters 01 function 1 framesize 00 function 1 upvalues number 01 function 1 collectable consts number 00 function 1 lua_number consts number 03 function 1 bytecode number function 1 bytecode begins 31 00 00 00 FNEW 0 0 30 00 00 80 UCLO 0 0 48 00 02 00 RET1 0 2 function 1 gc’able consts begins 00 gc’able const 0 type (type=BCDUMP_KGC_CHILD(0)) footer 00 bytecode file footer 2 Closure Factory 包 代码实现 2.1 Lua 5.1 下的实现 对于 Lua 5.1, 需要识别待加载字节码 header 中的 int、 size_t、Instruction 字长,相应构 建 closure factory 函数字节码, 并将原用户字节码的函数部分整体作为 closure factory 函数 的内部函数插入。例如, 对于 int、size_t、Instruction 字长分别为 4、 4 的 Lua 平台下编译 8、 7
  • 8.
    2.2 LuaJIT 2.0下的实现 2 CLOSURE FACTORY 包 代码实现 出的用户字节码,构造 closure factory 的方法为: 1. 读入待加载字节码 header 并原样输出 2. 读取待加载字节码 body 数据中的 8(size_t) 字节长度,按此长度读出后续的 source 字符串内容,并将长度和字符串内容输出 3. 输出 int 字长的空 linedefined 字段: 0x00 0x00 0x00 0x00 4. 输出 int 字长的空 lastlinedefined 字段: 0x00 0x00 0x00 0x00 5. 输出 char 字长的空 nups 字段: 0x00 6. 输出 char 字长的空 numparams 字段: 0x00 7. 输出 char 字长的 is_vararg 字段值 2 表示 main chunk 为变参函数: 0x02 8. 输出 char 字长的 maxstacksize 默认值 2: 0x02 9. 输出 int 字长的 closure factory 函数字节码长度 3: 0x03 0x00 0x00 0x00 10. 输出 Instruction 字长的 3 条 closure factory 函数字节码: 0x24 0x00 0x00 0x00 0x1e 0x00 0x00 0x01 0x1e 0x00 0x80 0x00 11. 输出 int 字长的空 sizek 字段: 0x00 0x00 0x00 0x00 12. 输出 int 字长的 sizep 字段值 1, 以便将原用户字节码作为 closure factory 的内部函数 处理: 0x01 0x00 0x00 0x00 13. 插入待加载字节码 body 数据 14. 输出 int 字长的空 sizelineinfo 字段:0x00 0x00 0x00 0x00 15. 输出 int 字长的空 sizelocvars 字段:0x00 0x00 0x00 0x00 16. 输出 int 字长的空 sizeupvalues 字段:0x00 0x00 0x00 0x00 17. 完成! 2.2 LuaJIT 2.0 下的实现 LuaJIT 2.0 的字节码是平台无关的, 且父函数总在其子函数之后输出,故添加 closure factory 时比 Lua 5.1 简单的多,方法为: 1. 读入全部待加载字节码数据,截去末尾 footer 的 1 字节后原样输出 2. 输出 ULEB128 编码方式的 closure factory 函数剩余数据长度 20: 0x14 3. 输出 closure factory 函数标志字节 (no ffi, vararg, has child): 0x03 4. 输出 char 字长的空 numparams 字段:0x00 5. 输出 char 字长的默认 framesize 字段:0x01 6. 输出 char 字长的空 nups 字段:0x00 7. 输出 ULEB128 编码方式的可回收常量计数 1,因为 closure factory 仅引用目标字节 码这一常量:0x01 8
  • 9.
    3 字节码参考 8. 输出 ULEB128 编码方式的数值常量计数 0:0x00 9. 输出 ULEB128 编码方式的 closure factory 字节码数量 3:0x03 10. 输出 int32_t 字长的 3 条 closure factory 字节码:0x31 0x00 0x00 0x00 0x30 0x00 0x00 0x80 0x48 0x00 0x02 0x00 11. 输出含有目标字节码占位空间的可回收常量区:0x00 12. 输出末尾 footer:0x00 13. 完成! 3 字节码参考 3.1 Lua 5.1 字节码种类 参考 lopcodes.h 3.2 Lua 5.1 字节码列表 符 OPCODE 参数 式 能 LOADK 0x01 iABx GETGLOBAL 0x05 iABx CALL 0x1c iABC RETURN 0x1e iABC CLOSURE 0x24 iABx 3.3 LuaJIT 2.0 字节码种类 参考 lj_bc.h 9
  • 10.
    3.4 LuaJIT 2.0字节码列表 3 字节码参考 3.4 LuaJIT 2.0 字节码列表 符 OPCODE 参数 式 能 KSTR 0x25 AD UCLO 0x30 AD FNEW 0x31 AD GGET 0x34 AD CALL 0x3e ABC RET0 0x47 AD RET1 0x48 AD 10