lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hello list,

I'm working on a website similar to Godbolt.org for Lua, and I'm trying to get as much information in the decompilation as possible to make the instructions as clear as possible. I'm now looking at the TFORCALL instruction in Lua 5.4 and Lua 5.3, which has me a bit confused. I might be missing something obvious.

Consider the next code and luac -p -l -l output:

 Input:

local t = {};

for key, value in pairs(t) do
        print(key, value);
end

for test1, test2, test3, test4 in somepairs(t) do
        print(test1, test2, test3, test4);
end

Output:

main <TFORCALL.lua:0,0> (28 instructions at 0x559fb6d9aca0)
0+ params, 14 slots, 1 upvalue, 15 locals, 3 constants, 0 functions
        1       [1]     VARARGPREP      0
        2       [1]     NEWTABLE        0 0 0
        3       [1]     EXTRAARG        0
        4       [3]     GETTABUP        1 0 0   ; _ENV "pairs"
        5       [3]     MOVE            2 0
        6       [3]     CALL            1 2 5   ; 1 in 4 out
        7       [3]     TFORPREP        1 4     ; to 12
        8       [4]     GETTABUP        7 0 1   ; _ENV "print"
        9       [4]     MOVE            8 5
        10      [4]     MOVE            9 6
        11      [4]     CALL            7 3 1   ; 2 in 0 out
        12      [3]     TFORCALL        1 2
        13      [3]     TFORLOOP        1 6     ; to 8
        14      [5]     CLOSE           1
        15      [7]     GETTABUP        1 0 2   ; _ENV "somepairs"
        16      [7]     MOVE            2 0
        17      [7]     CALL            1 2 5   ; 1 in 4 out
        18      [7]     TFORPREP        1 6     ; to 25
        19      [8]     GETTABUP        9 0 1   ; _ENV "print"
        20      [8]     MOVE            10 5
        21      [8]     MOVE            11 6
        22      [8]     MOVE            12 7
        23      [8]     MOVE            13 8
        24      [8]     CALL            9 5 1   ; 4 in 0 out
        25      [7]     TFORCALL        1 4
        26      [7]     TFORLOOP        1 8     ; to 19
        27      [9]     CLOSE           1
        28      [9]     RETURN          1 1 1   ; 0 out
constants (3) for 0x559fb6d9aca0:
        0       S       "pairs"
        1       S       "print"
        2       S       "somepairs"
locals (15) for 0x559fb6d9aca0:
        0       t               4       29
        1       (for state)     7       15
        2       (for state)     7       15
        3       (for state)     7       15
        4       (for state)     7       15
        5       key             8       12
        6       value           8       12
        7       (for state)     18      28
        8       (for state)     18      28
        9       (for state)     18      28
        10      (for state)     18      28
        11      test1           19      25
        12      test2           19      25
        13      test3           19      25
        14      test4           19      25
upvalues (1) for 0x559fb6d9aca0:
        0       _ENV            1       0


For the case of Lua 5.4, in TFORCALL R(A) holds the generator, R(A + 1) the state, R(A + 2) the control variable and R(A + 3) the to be closed variable.
R(A + 4) through R(A + 3 + C) will hold the local values specified in the for loop, returned by the generator. Am I correct about this?

If so, usually when a register is referring to a local then the local can easily be resolved by looking up the value of A in the locals list for that function. Am
I correct that in the case of TFORCALL, A is relative to the first local that the PC of TFORCALL falls within? (TFORCALL PC >= local startpc && TFORCALL PC <= local endpc)

Should this always be the approach of resolving a local referenced in a register? Please correct me if I'm horribly wrong, I want to learn about Lua bytecode.

Thanks,
Bas