lua-users home
lua-l archive

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



Roberto Ierusalimschy <roberto@inf.puc-rio.br> 于2021年7月10日周六 上午12:38写道:
>       I'm reading the source code of lua515, there is some code then I
> don't understand yet
>
> int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
>    luaK_dischargevars(fs, e);
>   if (e->k == VNONRELOC) {
>     if (!hasjumps(e)) return e->u.s.info;  /* exp is already in a register
> */
>     if (e->u.s.info >= fs->nactvar) {  /* reg. is not a local? */
>       exp2reg(fs, e, e->u.s.info);  /* put value on it */
>       return e->u.s.info;
>     }
>   }
>   luaK_exp2nextreg(fs, e);  /* default */
>   return e->u.s.info;
> }
>
> Here is a branch "e->u.s.info >= fs->nactvar", I don't quite understand,
> can anyone explain the relevant context or example? thank you all.

As the comment explains, the test checks whether the register holds
a local variable. If it does, we cannot change its value, so we put
the value in the next available register (luaK_exp2nextreg). Otherwise,
the final value can live where it is.

As an example, consider the code below:

  local a1,a2
  do
    return (a1 or a2) + 1
  end
  do
    return a1 or (a2 + 1)
  end

It generates the follwoing opcodes. (This is 5.3, but the general idea
is the same.)

        1       [1]     LOADNIL         0 1
        2       [3]     TESTSET         2 0 1
        3       [3]     JMP             0 1     ; to 5
        4       [3]     MOVE            2 1
        5       [3]     ADD             2 2 -1  ; - 1
        6       [3]     RETURN          2 2
        7       [6]     TESTSET         2 0 1
        8       [6]     JMP             0 1     ; to 10
        9       [6]     ADD             2 1 -1  ; - 1
        10      [6]     RETURN          2 2

In the first case (lines 2-6), it cannot put the final result in
register 1, because it cannot change a2. So, it has to put the
result in register 2, and therefore needs a move (line 4). In
the second case, the results are already in register 2, which is
not a variable, so they stay there and there is no need for a move.

-- Roberto