lua-users home
lua-l archive

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


On 5 August 2015 at 20:54, Dibyendu Majumdar <mobile@majumdar.org.uk> wrote:
> On 5 August 2015 at 14:49, Roberto Ierusalimschy <roberto@inf.puc-rio.br> wrote:
>>> The Lua code does following in OP_RETURN:
>>>
>>>         int b = GETARG_B(i);
>>>         if (cl->p->sizep > 0) luaF_close(L, base);
>>>         b = luaD_poscall(L, ra, (b != 0 ? b - 1 : L->top - ra));
>>>         if (!(ci->callstatus & CIST_REENTRY))  /* 'ci' still the called one */
>>>           return;  /* external invocation: return */
>>>         else {  /* invocation via reentry: continue execution */
>>>           ci = L->ci;
>>>           if (b) L->top = ci->top;
>>>           lua_assert(isLua(ci));
>>>           lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL);
>>>           goto newframe;  /* restart luaV_execute over new Lua function */
>>>         }
>>>
>>> It is not clear to me why in the external invocation case, if
>>> following code is not executed:
>>>
>>>           ci = L->ci;
>>>           if (b) L->top = ci->top;
>>
>> Both statements here prepare 'luaV_execute' to run the function
>> "OP_RETURN" is returning *to*. (The previous call to 'luaD_poscall'
>> already updated 'L->ci' to point to this previous entry.) When
>> the running function (the one returning *from*) was called
>> externally (e.g., from a C function), 'luaV_execute' returns,
>> so this preparation would be meaningless.
>
> Updating the variable 'ci' is meaningless but I don't see why the
> setting of 'L->top' is also meaningless, given what you stated below.
> Specially consider this:
>
> When a Lua function is JIT compiled, this is equivalent roughly to
> creating a custom version of luaV_execute(). So when a JITed Lua
> function calls another JITed Lua function, it is equivalent to
> invoking luaV_execute() for each Lua function. Therefore the
> adjustment to 'L->top' is still required in this case?
>

Where I have got to so far is that basically in JIT mode, if OP_CALL
results in calling a Lua function (whether interpreted and therefore
via luaV_execute() - or as a JIT compiled function) then the following
needs to be executed in OP_RETURN as when CIST_REENTRY is true.

     if (b) L->top = L->ci->top;

However in any other scenario OP_RETURN when called externally must not do this.

So essentially I am replicating the behaviour of OP_RETURN when
CIST_REENTRY is true, and the reason this is necessary is that there
is a difference in how OP_RETURN behaves in the two cases.

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?

Regards
Dibyendu