aboutsummaryrefslogtreecommitdiff
path: root/lcode.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2009-08-10 12:31:44 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2009-08-10 12:31:44 -0300
commit1b4480003b1bfa7e1d34e587ebd19a9de63c6467 (patch)
tree2c1ded051c89e62a49c156c63a1ccfde9f8818c1 /lcode.c
parent42167804b89b26428dea98b97549892c24623d71 (diff)
downloadlua-1b4480003b1bfa7e1d34e587ebd19a9de63c6467.tar.gz
lua-1b4480003b1bfa7e1d34e587ebd19a9de63c6467.tar.bz2
lua-1b4480003b1bfa7e1d34e587ebd19a9de63c6467.zip
"stange numbers" (-0 and NaN) also go to the constant table (as
strings with their binary representation). Therefore, constant folding may produce these results.
Diffstat (limited to 'lcode.c')
-rw-r--r--lcode.c45
1 files changed, 29 insertions, 16 deletions
diff --git a/lcode.c b/lcode.c
index 3371b71c..1fe5874f 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 2.39 2009/06/17 17:49:09 roberto Exp roberto $ 2** $Id: lcode.c,v 2.40 2009/06/18 16:35:05 roberto Exp roberto $
3** Code generator for Lua 3** Code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -21,6 +21,7 @@
21#include "lobject.h" 21#include "lobject.h"
22#include "lopcodes.h" 22#include "lopcodes.h"
23#include "lparser.h" 23#include "lparser.h"
24#include "lstring.h"
24#include "ltable.h" 25#include "ltable.h"
25 26
26 27
@@ -224,22 +225,24 @@ static int addk (FuncState *fs, TValue *key, TValue *v) {
224 lua_State *L = fs->L; 225 lua_State *L = fs->L;
225 TValue *idx = luaH_set(L, fs->h, key); 226 TValue *idx = luaH_set(L, fs->h, key);
226 Proto *f = fs->f; 227 Proto *f = fs->f;
227 int k; 228 int k, oldsize;
228 if (ttisnumber(idx)) { 229 if (ttisnumber(idx)) {
229 lua_Number n = nvalue(idx); 230 lua_Number n = nvalue(idx);
230 lua_number2int(k, n); 231 lua_number2int(k, n);
231 lua_assert(luaO_rawequalObj(&f->k[k], v)); 232 if (luaO_rawequalObj(&f->k[k], v))
232 } 233 return k;
233 else { /* constant not found; create a new entry */ 234 /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0");
234 int oldsize = f->sizek; 235 go through and create a new entry for this value */
235 k = fs->nk;
236 setnvalue(idx, cast_num(k));
237 luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Bx, "constants");
238 while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
239 setobj(L, &f->k[k], v);
240 fs->nk++;
241 luaC_barrier(L, f, v);
242 } 236 }
237 /* constant not found; create a new entry */
238 oldsize = f->sizek;
239 k = fs->nk;
240 setnvalue(idx, cast_num(k));
241 luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Bx, "constants");
242 while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
243 setobj(L, &f->k[k], v);
244 fs->nk++;
245 luaC_barrier(L, f, v);
243 return k; 246 return k;
244} 247}
245 248
@@ -252,9 +255,20 @@ int luaK_stringK (FuncState *fs, TString *s) {
252 255
253 256
254int luaK_numberK (FuncState *fs, lua_Number r) { 257int luaK_numberK (FuncState *fs, lua_Number r) {
258 int n;
259 lua_State *L = fs->L;
255 TValue o; 260 TValue o;
256 setnvalue(&o, r); 261 setnvalue(&o, r);
257 return addk(fs, &o, &o); 262 if (r == 0 || luai_numisnan(NULL, r)) { /* handle -0 and NaN */
263 /* use raw representation as key to avoid numeric problems */
264 setsvalue(L, L->top, luaS_newlstr(L, (char *)&r, sizeof(r)));
265 incr_top(L);
266 n = addk(fs, L->top - 1, &o);
267 L->top--;
268 }
269 else
270 n = addk(fs, &o, &o); /* regular case */
271 return n;
258} 272}
259 273
260 274
@@ -643,7 +657,6 @@ static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
643 if ((op == OP_DIV || op == OP_MOD) && e2->u.nval == 0) 657 if ((op == OP_DIV || op == OP_MOD) && e2->u.nval == 0)
644 return 0; /* do not attempt to divide by 0 */ 658 return 0; /* do not attempt to divide by 0 */
645 r = luaO_arith(op - OP_ADD + LUA_OPADD, e1->u.nval, e2->u.nval); 659 r = luaO_arith(op - OP_ADD + LUA_OPADD, e1->u.nval, e2->u.nval);
646 if (luai_numisnan(NULL, r)) return 0; /* do not attempt to produce NaN */
647 e1->u.nval = r; 660 e1->u.nval = r;
648 return 1; 661 return 1;
649} 662}
@@ -690,7 +703,7 @@ void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
690 e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; 703 e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
691 switch (op) { 704 switch (op) {
692 case OPR_MINUS: { 705 case OPR_MINUS: {
693 if (isnumeral(e) && e->u.nval != 0) /* minus non-zero constant? */ 706 if (isnumeral(e)) /* minus constant? */
694 e->u.nval = luai_numunm(NULL, e->u.nval); /* fold it */ 707 e->u.nval = luai_numunm(NULL, e->u.nval); /* fold it */
695 else { 708 else {
696 luaK_exp2anyreg(fs, e); 709 luaK_exp2anyreg(fs, e);