lua-users home
lua-l archive

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


On 6 August 2015 at 22:55, Roberto Ierusalimschy <roberto@inf.puc-rio.br> wrote:
>> I feel this is a bit unsatisfactory as really luaV_execute() should
>> always do the right thing. But I think the issue stems from the fact
>> that 'L->top' is being used to convey information as you have
>> described above.
>>
>> Is it possible to consider an implementation where L->top is strictly
>> the top of the stack, and not used for a dual purpose? Or am I missing
>> a point here?
>
> It is not only L->top that has a dual purpose; the stack has a dual
> usage, due to the way that Lua uses a register-based VM. While inside
> a Lua function, Lua preallocates in the stack all "registers" that the
> function will eventually need. So, while running VM instructions in
> one function, L->top points to the end of its activation record (stack
> frame). When Lua enters or re-enters a Lua function, L->top must be
> corrected to this frame, except when multiple returns are involved.
> In that case, it is true that L->top is used to pass information
> strictly between two consecutive VM instructions. (From either
> OP_CALL/OP_VARARG to one of OP_CALL/OP_RETURN/OP_SETLIST.)
>
> Maybe we could use a local variable inside luaV_execute for that task?
>

But would that work in coroutines when control has to return to the
function? I was wondering if there should be another field in
lua_State to hold the value of L->top in this case? I wish I
understood more to be able to offer a solution :-(

Just for the record I am solving the issue in Ravi in the following way.

When luaV_execute() is invoked, it may be as a result of an OP_CALL,
or an external call.
So I am doing following:

In luaD_precall() I pass an extra argument to say that this is an
OP_CALL. This is only true when luaD_precall() is invoked in OP_CALL
(or OP_TAILCALL).
I return the value of 'b' in luaV_execute() when OP_RETURN executes -
i.e. instead of being void function, it is an int function.

So then there are two cases:

A JIT function is invoked in luaD_precall() - think of the JIT
function as a custom luaV_execute() (Note that the JIT function is
directly executed within luaD_precall(), but not as a C function).
When the JIT function returns luaD_precall() checks if this was an
OP_CALL - and if 'b' is true (i.e. return value of JIT function), and
then it sets L->top to L->ci->top.

Second case is when a JIT function needs to call a Lua function in
interpreted mode via OP_CALL. In the generated JIT code for OP_CALL I
check 'b' returned by luaV_execute() and adjust L->top as above.

I just implemented this today so am still testing to see if this works
in all cases - i.e. when JIT calls interpreted, and when interpreted
calls JIT.

Regards