aboutsummaryrefslogtreecommitdiff
path: root/lcode.c
diff options
context:
space:
mode:
Diffstat (limited to 'lcode.c')
-rw-r--r--lcode.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/lcode.c b/lcode.c
index 208b2f9a..7a9cb6fb 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,10 +1,11 @@
1/* 1/*
2** $Id: lcode.c,v 2.69 2013/05/06 17:22:16 roberto Exp roberto $ 2** $Id: lcode.c,v 2.70 2013/06/20 17:37:31 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*/
6 6
7 7
8#include <math.h>
8#include <stdlib.h> 9#include <stdlib.h>
9 10
10#define lcode_c 11#define lcode_c
@@ -26,6 +27,14 @@
26#include "lvm.h" 27#include "lvm.h"
27 28
28 29
30/* test for x == -0 */
31#if defined(signbit)
32#define isminuszero(x) ((x) == 0.0 && signbit(x))
33#else
34#define isminuszero(x) ((x) == 0.0 && 1.0/(x) < 0.0)
35#endif
36
37
29#define hasjumps(e) ((e)->t != (e)->f) 38#define hasjumps(e) ((e)->t != (e)->f)
30 39
31 40
@@ -332,30 +341,28 @@ int luaK_stringK (FuncState *fs, TString *s) {
332} 341}
333 342
334 343
344/*
345** use userdata as key to avoid collision with float with same value;
346** conversion to 'void*' used only for hash, no "precision" problems
347*/
335int luaK_intK (FuncState *fs, lua_Integer n) { 348int luaK_intK (FuncState *fs, lua_Integer n) {
336 TValue k, o; 349 TValue k, o;
337 /* use userdata as key to avoid collision with float with same value;
338 conversion to 'void*' used only for hash, no "precision" problems */
339 setpvalue(&k, cast(void*, cast(size_t, n))); 350 setpvalue(&k, cast(void*, cast(size_t, n)));
340 setivalue(&o, n); 351 setivalue(&o, n);
341 return addk(fs, &k, &o); 352 return addk(fs, &k, &o);
342} 353}
343 354
344 355
356/*
357** Both NaN and -0.0 should not go to the constant table, as they have
358** problems with the hashing. (NaN is not ** a valid key,
359** -0.0 collides with +0.0.)
360*/
345static int luaK_numberK (FuncState *fs, lua_Number r) { 361static int luaK_numberK (FuncState *fs, lua_Number r) {
346 int n;
347 lua_State *L = fs->ls->L;
348 TValue o; 362 TValue o;
363 lua_assert(!luai_numisnan(NULL, r) && !isminuszero(r));
349 setnvalue(&o, r); 364 setnvalue(&o, r);
350 if (r != 0 && !luai_numisnan(NULL, r)) /* avoid -0 and NaN */ 365 return addk(fs, &o, &o);
351 n = addk(fs, &o, &o); /* regular case */
352 else { /* handle -0 and NaN */
353 /* use raw representation as key to avoid numeric problems */
354 setsvalue(L, L->top++, luaS_newlstr(L, (char *)&r, sizeof(r)));
355 n = addk(fs, L->top - 1, &o);
356 L->top--;
357 }
358 return n;
359} 366}
360 367
361 368
@@ -755,8 +762,11 @@ static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
755 e1->u.ival = ivalue(&res); 762 e1->u.ival = ivalue(&res);
756 } 763 }
757 else { 764 else {
765 lua_Number n = fltvalue(&res);
766 if (luai_numisnan(NULL, n) || isminuszero(n))
767 return 0; /* folds neither NaN nor -0 */
758 e1->k = VKFLT; 768 e1->k = VKFLT;
759 e1->u.nval = fltvalue(&res); 769 e1->u.nval = n;
760 } 770 }
761 return 1; 771 return 1;
762} 772}