Lua source code `hello.lua` ```lua print "Hello." ``` `math.lua` ```lua local function add (a, b) return a + b end print (("1 + 2 = %i"):format (add (1, 2))) ``` luac5.4 listing ``` main (5 instructions at 0x564f4fd74cc0) 0+ params, 2 slots, 1 upvalue, 0 locals, 2 constants, 0 functions 1 [1] VARARGPREP 0 2 [1] GETTABUP 0 0 0 ; _ENV "print" 3 [1] LOADK 1 1 ; "Hello." 4 [1] CALL 0 2 1 ; 1 in 0 out 5 [1] RETURN 0 1 1 ; 0 out ``` ``` main (12 instructions at 0x55ee2417acc0) 0+ params, 7 slots, 1 upvalue, 1 local, 3 constants, 1 function 1 [1] VARARGPREP 0 2 [3] CLOSURE 0 0 ; 0x55ee2417b000 3 [5] GETTABUP 1 0 0 ; _ENV "print" 4 [5] LOADK 2 1 ; "1 + 2 = %i" 5 [5] SELF 2 2 2k ; "format" 6 [5] MOVE 4 0 7 [5] LOADI 5 1 8 [5] LOADI 6 2 9 [5] CALL 4 3 0 ; 2 in all out 10 [5] CALL 2 0 0 ; all in all out 11 [5] CALL 1 0 1 ; all in 0 out 12 [5] RETURN 1 1 1 ; 0 out function (4 instructions at 0x55ee2417b000) 2 params, 3 slots, 0 upvalues, 2 locals, 0 constants, 0 functions 1 [2] ADD 2 0 1 2 [2] MMBIN 0 1 6 ; __add 3 [2] RETURN1 2 4 [3] RETURN0 ``` ``` main (14 instructions at 0x559f55e1ecd0) 0+ params, 2 slots, 1 upvalue, 1 local, 5 constants, 1 function 1 [1] VARARGPREP 0 2 [1] GETTABUP 0 0 0 ; _ENV "arg" 3 [1] GETI 0 0 1 4 [1] EQK 0 1 0 ; "93" 5 [1] JMP 4 ; to 10 6 [2] GETTABUP 0 0 2 ; _ENV "print" 7 [2] LOADK 1 3 ; "it's 93" 8 [2] CALL 0 2 1 ; 1 in 0 out 9 [2] JMP 3 ; to 13 10 [4] GETTABUP 0 0 2 ; _ENV "print" 11 [4] LOADK 1 4 ; "it's not 93" 12 [4] CALL 0 2 1 ; 1 in 0 out 13 [9] CLOSURE 0 0 ; 0x559f55e1f3d0 14 [9] RETURN 1 1 1 ; 0 out constants (5) for 0x559f55e1ecd0: 0 S "arg" 1 S "93" 2 S "print" 3 S "it's 93" 4 S "it's not 93" locals (1) for 0x559f55e1ecd0: 0 unused_fn 14 15 upvalues (1) for 0x559f55e1ecd0: 0 _ENV 1 0 function (4 instructions at 0x559f55e1f3d0) 0 params, 2 slots, 1 upvalue, 0 locals, 2 constants, 0 functions 1 [8] GETTABUP 0 0 0 ; _ENV "print" 2 [8] LOADK 1 1 ; "unused" 3 [8] CALL 0 2 1 ; 1 in 0 out 4 [9] RETURN0 constants (2) for 0x559f55e1f3d0: 0 S "print" 1 S "unused" locals (0) for 0x559f55e1f3d0: upvalues (1) for 0x559f55e1f3d0: 0 _ENV 0 0 ``` Octal dump of luac5.4 byte code ``` 0000000 1b 4c 75 61 54 00 19 93 0d 0a 1a 0a 04 08 08 78 >.LuaT..........x< 0000020 56 00 00 00 00 00 00 00 00 00 00 00 28 77 40 01 >V...........(w@.< 0000040 8b 40 68 65 6c 6c 6f 2e 6c 75 61 80 80 00 01 02 >.@hello.lua.....< 0000060 85 51 00 00 00 0b 00 00 00 83 80 00 00 44 00 02 >.Q...........D..< 0000100 01 46 00 01 01 82 04 86 70 72 69 6e 74 04 87 48 >.F......print..H< 0000120 65 6c 6c 6f 2e 81 01 00 00 80 85 01 00 00 00 00 >ello............< 0000140 80 80 81 85 5f 45 4e 56 >...._ENV< 0000150 ``` ``` 0000000 1b 4c 75 61 54 00 19 93 0d 0a 1a 0a 04 08 08 78 >.LuaT..........x< 0000020 56 00 00 00 00 00 00 00 00 00 00 00 28 77 40 01 >V...........(w@.< 0000040 8a 40 6d 61 74 68 2e 6c 75 61 80 80 00 01 07 8c >.@math.lua......< 0000060 51 00 00 00 4f 00 00 00 8b 00 00 00 03 81 00 00 >Q...O...........< 0000100 14 81 02 02 00 02 00 00 81 02 00 80 01 83 00 80 >................< 0000120 44 02 03 00 44 01 00 00 c4 00 00 01 c6 00 01 01 >D...D...........< 0000140 83 04 86 70 72 69 6e 74 04 8b 31 20 2b 20 32 20 >...print..1 + 2 < 0000160 3d 20 25 69 04 87 66 6f 72 6d 61 74 81 01 00 00 >= %i..format....< 0000200 81 80 81 83 02 00 03 84 22 01 00 01 2e 00 01 06 >........".......< 0000220 48 01 02 00 47 01 01 00 80 80 80 84 01 00 00 01 >H...G...........< 0000240 80 82 82 61 80 84 82 62 80 84 80 8c 01 02 02 00 >...a...b........< 0000260 00 00 00 00 00 00 00 00 80 81 84 61 64 64 82 8c >...........add..< 0000300 81 85 5f 45 4e 56 >.._ENV< 0000306 ``` # Interpretation of byte code Overall structure - Roughly 32 byte header with magic number, version number, etc. - File name - `80 80 00 01 02 85` header for main function - Packed 4-byte instructions for main function - `82` or `83` length prefix for string table - String table for main function - `81 01 00 00 81 80 81 83 02 00 03 84` header for "add" function - Packed 4-byte instructions for "add" function - `80 80 80 84 01 00 00 01 80` Header for file-scope debug symbols? - File-scope debug symbols? - String table for entire file? ## Bytecodes Per lopcodes.h, instructions are 32 bits long, always. The opcode is encoded in the first (highest?) 7 bits. ``` 83 80 00 00 ; 0x03 = 3 = LOADK 0b 00 00 00 ; 0x0b = 11 = GETTABUP 22 01 00 01 ; 0x22 = 34 = ADD 2e 00 01 06 ; 0x2e = 46 = MMBIN c4 00 00 01 ; 0xc4 = 68 = CALL 44 00 02 01 ; 0x44 = 68 = CALL 46 00 01 01 ; 0x46 = 70 = RETURN 47 01 01 00 ; 0x47 = 71 = RETURN0 48 01 02 00 ; 0x48 = 72 = RETURN1 51 00 00 00 ; 0x51 = 81 = VARARGPREP ``` ## Strings Filenames are encoded at the top, and there's a string table at the bottom. Strings appear to be prefixed with a variable-length length prefix. There is an extra byte before each string which I can't account for, and the lengths seem to be off by one, e.g. 0x84 is a length of 3, not 4. | --- | | "add" | 81 84 61 64 64 | "_ENV" | 81 85 5f 45 4e 56 | "print" | 04 86 70 72 69 6e 74 | "format" | 04 87 66 6f 72 6d 61 74 | "@math.lua" | 01 8a 40 6d 61 74 68 2e 6c 75 61 | "1 + 2 = %i" | 04 8b 31 20 2b 20 32 20 3d 20 25 69