lua-users home
lua-l archive

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


On Mon, Mar 21, 2016 at 6:04 PM, Scott Morgan <blumf@blueyonder.co.uk> wrote:
> On 21/03/16 21:07, René Rebe wrote:
>> On Mar 21, 2016, at 17:12, Coda Highland <chighland@gmail.com> wrote:
>>> On Mon, Mar 21, 2016 at 9:10 AM, Scott Morgan <blumf@blueyonder.co.uk> wrote:
>>>> On 21/03/16 15:59, Dirk Laurie wrote:
>>>>> 2016-03-21 16:32 GMT+02:00 Wangbo <wangbo.red@gmail.com>:
>>>>>> I have simple Lua code, why have two RETURN opcode for foo function after i
>>>>>> check compile code.
>>>>>>
>>>>>> 6 [4] RETURN   1 2
>>>>>> 7 [5] RETURN   0 1
>>>>>
>>>>> Checking all code paths to make sure that the `end` statement
>>>>> cannot be reached would make the compiler more complicated.
>>>>
>>>> Is this an overhead of supporting gotos?
>>>
>>> Considering this is bytecode and everything from loops to conditionals
>>> are implemented as jumps? You could say that. But it's not
>>> specifically tied to the "goto" language feature; it would still be
>>> relevant even if you couldn't use "goto" in Lua code.
>>
>> IIRC older Lua versions indeed already simply did this too.
>> At least I remember seeing this in 5.1 which did not yet had gotos, …
>
> Interesting. In what situations (i.e. what kind of source code) does
> this become an issue that the extra return is needed? Error handling?
>
> Scott
>
>

I've not checked a bytecode dump to see if this is actually a REAL
example, but consider this general concept:

function foo()
  if bar then
    return 1
  end
end

If bar is false, then it's going to do a jump over the body of the
conditional. But the "end" corresponding to the "if" doesn't actually
do anything; it's just a marker for a position in between statements.
And the next thing that has to happen is an implicit return from the
function because you've walked off the end of it. So that means you've
got two returns in a row, and that second one is actually important
because the first one might very reasonably be skipped.

It isn't even THEORETICALLY possible to avoid this in every possible
case, too -- it's a textbook example of the halting problem. If you
could figure out with 100% certainty that every possible code path
could never walk off the end of the function, you could take the
"extra" RETURN opcode out. But it's always possible to write code
where you can't be 100% sure -- as a very simple example, consider a
function that contains a while loop predicated on a global variable.
The loop termination condition isn't even contained inside the
function anymore!

So instead of trying to get fancy and save a few bytes by figuring out
if an extra RETURN is necessary or not... why bother? Skip the
overkill code analysis, output a RETURN opcode unconditionally, and
call it a day. The code generator is substantially leaner,
substantially faster, and has less surface area for errors -- that's a
pretty good win.

/s/ Adam