mirror of https://github.com/rusefi/lua.git
"stange numbers" (-0 and NaN) also go to the constant table (as
strings with their binary representation). Therefore, constant folding may produce these results.
This commit is contained in:
parent
42167804b8
commit
1b4480003b
45
lcode.c
45
lcode.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lcode.c,v 2.39 2009/06/17 17:49:09 roberto Exp roberto $
|
** $Id: lcode.c,v 2.40 2009/06/18 16:35:05 roberto Exp roberto $
|
||||||
** Code generator for Lua
|
** Code generator for Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -21,6 +21,7 @@
|
||||||
#include "lobject.h"
|
#include "lobject.h"
|
||||||
#include "lopcodes.h"
|
#include "lopcodes.h"
|
||||||
#include "lparser.h"
|
#include "lparser.h"
|
||||||
|
#include "lstring.h"
|
||||||
#include "ltable.h"
|
#include "ltable.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -224,22 +225,24 @@ static int addk (FuncState *fs, TValue *key, TValue *v) {
|
||||||
lua_State *L = fs->L;
|
lua_State *L = fs->L;
|
||||||
TValue *idx = luaH_set(L, fs->h, key);
|
TValue *idx = luaH_set(L, fs->h, key);
|
||||||
Proto *f = fs->f;
|
Proto *f = fs->f;
|
||||||
int k;
|
int k, oldsize;
|
||||||
if (ttisnumber(idx)) {
|
if (ttisnumber(idx)) {
|
||||||
lua_Number n = nvalue(idx);
|
lua_Number n = nvalue(idx);
|
||||||
lua_number2int(k, n);
|
lua_number2int(k, n);
|
||||||
lua_assert(luaO_rawequalObj(&f->k[k], v));
|
if (luaO_rawequalObj(&f->k[k], v))
|
||||||
}
|
return k;
|
||||||
else { /* constant not found; create a new entry */
|
/* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0");
|
||||||
int oldsize = f->sizek;
|
go through and create a new entry for this value */
|
||||||
k = fs->nk;
|
|
||||||
setnvalue(idx, cast_num(k));
|
|
||||||
luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Bx, "constants");
|
|
||||||
while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
|
|
||||||
setobj(L, &f->k[k], v);
|
|
||||||
fs->nk++;
|
|
||||||
luaC_barrier(L, f, v);
|
|
||||||
}
|
}
|
||||||
|
/* constant not found; create a new entry */
|
||||||
|
oldsize = f->sizek;
|
||||||
|
k = fs->nk;
|
||||||
|
setnvalue(idx, cast_num(k));
|
||||||
|
luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Bx, "constants");
|
||||||
|
while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
|
||||||
|
setobj(L, &f->k[k], v);
|
||||||
|
fs->nk++;
|
||||||
|
luaC_barrier(L, f, v);
|
||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,9 +255,20 @@ int luaK_stringK (FuncState *fs, TString *s) {
|
||||||
|
|
||||||
|
|
||||||
int luaK_numberK (FuncState *fs, lua_Number r) {
|
int luaK_numberK (FuncState *fs, lua_Number r) {
|
||||||
|
int n;
|
||||||
|
lua_State *L = fs->L;
|
||||||
TValue o;
|
TValue o;
|
||||||
setnvalue(&o, r);
|
setnvalue(&o, r);
|
||||||
return addk(fs, &o, &o);
|
if (r == 0 || luai_numisnan(NULL, r)) { /* handle -0 and NaN */
|
||||||
|
/* use raw representation as key to avoid numeric problems */
|
||||||
|
setsvalue(L, L->top, luaS_newlstr(L, (char *)&r, sizeof(r)));
|
||||||
|
incr_top(L);
|
||||||
|
n = addk(fs, L->top - 1, &o);
|
||||||
|
L->top--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
n = addk(fs, &o, &o); /* regular case */
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -643,7 +657,6 @@ static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
|
||||||
if ((op == OP_DIV || op == OP_MOD) && e2->u.nval == 0)
|
if ((op == OP_DIV || op == OP_MOD) && e2->u.nval == 0)
|
||||||
return 0; /* do not attempt to divide by 0 */
|
return 0; /* do not attempt to divide by 0 */
|
||||||
r = luaO_arith(op - OP_ADD + LUA_OPADD, e1->u.nval, e2->u.nval);
|
r = luaO_arith(op - OP_ADD + LUA_OPADD, e1->u.nval, e2->u.nval);
|
||||||
if (luai_numisnan(NULL, r)) return 0; /* do not attempt to produce NaN */
|
|
||||||
e1->u.nval = r;
|
e1->u.nval = r;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -690,7 +703,7 @@ void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
|
||||||
e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
|
e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case OPR_MINUS: {
|
case OPR_MINUS: {
|
||||||
if (isnumeral(e) && e->u.nval != 0) /* minus non-zero constant? */
|
if (isnumeral(e)) /* minus constant? */
|
||||||
e->u.nval = luai_numunm(NULL, e->u.nval); /* fold it */
|
e->u.nval = luai_numunm(NULL, e->u.nval); /* fold it */
|
||||||
else {
|
else {
|
||||||
luaK_exp2anyreg(fs, e);
|
luaK_exp2anyreg(fs, e);
|
||||||
|
|
Loading…
Reference in New Issue