lua-users home
lua-l archive

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


Kristofer Karlsson wrote:
> 2007/3/21, Thomas Lauer <thomas.lauer@virgin.net
> <mailto:thomas.lauer@virgin.net>>:
> 
>     Either I am doing something so stupid that I can't see it or something
>     fishy is going on. Consider this:
> 
>             function x(l)
>                     z=0
>                     l=nil
>                     return l
>             end
> 
>             print(x("test"))
> 
>     ... which prints "nil". Fine.
> 
>     Now simply comment out the first line of x() (ie "z=0") and try again...
>     this time it prints "test".
> 
>     It seems that the first line of x() can be any valid Lua statement other
>     than "l=nil" and all works fine. However, if this assignment is the
>     first line it just doesn't work. I am puzzled.
> 
>     (In case you wonder why anyone would set a function parameter to nil:
>     the above is stripped down to the smallest code snippet that shows this
>     behaviour. The original stuff comes from a more complex wrapper around a
>     bunch of functions in the Lua runtime library.)
> 
>     That's Lua 5.1.1 on a Win2k SP4 rollup box. I checked with both the
>     latest precompiled binaries and a locally compiled version.
> 
>     --
>     cheers  thomasl
> 
>     web : http://thomaslauer.com/start <http://thomaslauer.com/start>
> 
> 
> Strange indeed! Compiling "function(x) x = nil return x end" on lua
> 5.1.1 (from ubuntu lua package) gives a chunk that directly returns x.
> So, it's a compiler bug and not a virtual machine bug.
> My best guess (but it's nothing more than a guess) is that the compiler
> sees "assign nil to register 0" but doesn't see any previous assigment
> to register 0, thus falsely assuming that the operation can be optimized
> away.
> 
> 

You're right.

When the parser detects an assignment from a local variable to nil, it
calls luaK_nil() which checks if pc == 0 and skip assignment

if (fs->pc == 0)  /* function start? */
      return;  /* positions are already clean */

is the guilty code

To get rid of the bug, apply the attached patch to lcode.c

-- 
--
Julien Hamaide
Engineering Coach
10Tacle Studios Belgium / Elsewhere Entertainment
37,39c37,39
<   if (fs->pc > fs->lasttarget   /* no jumps to current position? */
<         && fs->pc != 0)  /* not function start? */
<   {
---
>   if (fs->pc > fs->lasttarget) {  /* no jumps to current position? */
>     if (fs->pc == 0)  /* function start? */
>       return;  /* positions are already clean */