[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: [Bug?] 0 vs -0 / Incorrect Optimization or Parsing
- From: Matthew Paul Del Buono <delbu9c1@...>
- Date: Tue, 28 Jul 2009 02:00:41 -0400 (EDT)
Hi all,
I think this has been raised before in IRC a year or two ago,
but I don't think there was ever a consensus on exactly what
the result should be.
Lua seems to have trouble parsing both -0 and 0 while reading
a file. Individually, it works fine, however when both are
present in the same file, the compiler seems to fold -0 and 0
into the same constant. Reference the following:
mpdelbuono@li23-154 ~ $ luac -l -
a = -0.0
main <stdin:0,0> (3 instructions, 12 bytes at 0x805fb30)
0+ params, 2 slots, 0 upvalues, 0 locals, 2 constants, 0
functions
1 [1] LOADK 0 -2 ; -0
2 [1] SETGLOBAL 0 -1 ; a
3 [1] RETURN 0 1
This wouldn't be an issue if -0 and 0 operated the same in all
situations (primarily because Lua follows that -0 == 0).
However, we encounter an issue in the situation where there is
an actual distinction between -0 and 0, like the following:
mpdelbuono@li23-154 ~ $ lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> return 1 / -0
-inf
> return 1 / 0
inf
Surely we all agree that -inf ~= inf, and as such 1/-0 ~= 1/0.
However, we get the following:
> return 1 / -0 == 1 / 0
true
Why does this happen? Because of the same problem:
mpdelbuono@li23-154 ~ $ luac -l -
return 1 / -0 == 1 /0
main <stdin:0,0> (8 instructions, 32 bytes at 0x805fb30)
0+ params, 2 slots, 0 upvalues, 0 locals, 2 constants, 0
functions
1 [1] DIV 0 -2 -1 ; 1 -0
2 [1] DIV 1 -2 -1 ; 1 -0
3 [1] EQ 1 0 1
4 [1] JMP 1 ; to 6
5 [1] LOADBOOL 0 0 1
6 [1] LOADBOOL 0 1 0
7 [1] RETURN 0 2
8 [1] RETURN 0 1
Again, notice the statement of 2 constants instead of the
expected 3. The flaw here is that it is being turned into "1
/0 == 1 / 0" instead of what was entered.
It seems Lua always chooses the first zero. Simply reversing
the sides of the expression will yield a different, but
equally incorrect, result:
mpdelbuono@li23-154 ~ $ luac -l -
return 1 / 0 == 1 / -0
main <stdin:0,0> (8 instructions, 32 bytes at 0x805fb30)
0+ params, 2 slots, 0 upvalues, 0 locals, 2 constants, 0
functions
1 [1] DIV 0 -2 -1 ; 1 0
2 [1] DIV 1 -2 -1 ; 1 0
3 [1] EQ 1 0 1
4 [1] JMP 1 ; to 6
5 [1] LOADBOOL 0 0 1
6 [1] LOADBOOL 0 1 0
7 [1] RETURN 0 2
8 [1] RETURN 0 1
If I had to venture a guess, Lua is making a naive check to
see if a constant is already present in the constants list by
checking equality directly, rather than actually checking if
they are truly the same constant.
Personally, I think this is a bug, but it is an extremely
borderline case. However, as shown above, it does in fact
cause incorrect bytecode to be generated in a very specific
use case.
Regards,
-- Matthew P. Del Buono
Embry-Riddle Aeronautical University