lua-users home
lua-l archive

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


2011/5/2 David Kastrup <dak@gnu.org>:
> Benoit Germain <bnt.germain@gmail.com> writes:
>
> What makes you think the former is a function call and the latter not?

The fact that select() is a C function that gets registered in the
main VM, and that nothing in the parser handles a call to select as
some special case that has to be optimized away.

> Have you actually looked at the generated byte code?

It wasn't necessary, but since you ask, let' have vararg.lua:

function f1( ...) return #... end
function f2( ...) return select( '#', ...) end

luac -l vararg.lua:

function <vararg.lua:1,3> (4 instructions, 16 bytes at 005FE120)
0+ params, 2 slots, 0 upvalues, 1 local, 0 constants, 0 functions
        1       [2]     VARARG          1 2
        2       [2]     LEN             1 1
        3       [2]     RETURN          1 2
        4       [3]     RETURN          0 1

What this does is retrieve the contents of '...', then apply OP_LEN on
the first one (possibly invoking __len, of course). As far as I can
see, OP_VARARG is always generated by the compiler as "push everything
on the stack", and can possibly be modified later by changing B so
that it does "push only that many elements on the stack". I haven't
checked if this is the case when writing # ... .

function <vararg.lua:5,7> (6 instructions, 24 bytes at 005FE190)
0+ params, 4 slots, 0 upvalues, 1 local, 2 constants, 0 functions
        1       [6]     GETGLOBAL       1 -1    ; select
        2       [6]     LOADK           2 -2    ; "#"
        3       [6]     VARARG          3 0
        4       [6]     TAILCALL        1 0 0
        5       [6]     RETURN          1 0
        6       [7]     RETURN          0 1

This fetches function select, pushes '#', then all elements of '...',
then calls the function. QED.

-- 
Benoit.