From fd80e63468f0c08fedd8dbf944fa4954b72d7384 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Mon, 13 Jun 2011 11:13:06 -0300 Subject: [PATCH] configuration for NaN trick big-endian + macro 'luai_checknum' to ensure numbers comming from C are not "improper" (some kinds of signaling NaNs) --- lapi.c | 4 +++- lobject.h | 21 +++++++++++++++++++-- luaconf.h | 32 ++++++++++++++++++++++++++++---- 3 files changed, 50 insertions(+), 7 deletions(-) diff --git a/lapi.c b/lapi.c index 8fd9ba86..b2035931 100644 --- a/lapi.c +++ b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 2.147 2011/05/31 18:27:56 roberto Exp roberto $ +** $Id: lapi.c,v 2.148 2011/06/02 19:31:40 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -463,6 +463,8 @@ LUA_API void lua_pushnil (lua_State *L) { LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { lua_lock(L); setnvalue(L->top, n); + luai_checknum(L, L->top, + luaG_runerror(L, "C API - attempt to push a signaling NaN")); api_incr_top(L); lua_unlock(L); } diff --git a/lobject.h b/lobject.h index c130dcb6..5221ab68 100644 --- a/lobject.h +++ b/lobject.h @@ -1,5 +1,5 @@ /* -** $Id: lobject.h,v 2.58 2011/06/07 19:02:33 roberto Exp roberto $ +** $Id: lobject.h,v 2.59 2011/06/09 18:21:25 roberto Exp roberto $ ** Type definitions for Lua objects ** See Copyright Notice in lua.h */ @@ -262,7 +262,7 @@ typedef struct lua_TValue TValue; ** ======================================================= */ -#if defined(LUA_NANTRICK) +#if defined(LUA_NANTRICKLE) || defined(LUA_NANTRICKBE) /* ** numbers are represented in the 'd_' field. All other values have the @@ -270,11 +270,20 @@ typedef struct lua_TValue TValue; ** a "signaled NaN", which is never generated by regular operations by ** the CPU (nor by 'strtod') */ +#if !defined(NNMARK) #define NNMARK 0x7FF7A500 +#endif #undef TValuefields +#if defined(LUA_NANTRICKLE) +/* little endian */ #define TValuefields \ union { struct { Value v_; int tt_; } i; double d_; } u +#else +/* big endian */ +#define TValuefields \ + union { struct { int tt_; Value v_; } i; double d_; } u +#endif #undef numfield #define numfield /* no such field; numbers are the entire struct */ @@ -322,6 +331,14 @@ typedef struct lua_TValue TValue; (ttisnumber(o1) ? ttisnumber(o2) : ((o1)->u.i.tt_ == (o2)->u.i.tt_)) + +#define luai_checknum(L,o,c) { if (!ttisnumber(o)) c; } + + +#else + +#define luai_checknum(L,o,c) { /* empty */ } + #endif /* }====================================================== */ diff --git a/luaconf.h b/luaconf.h index 202655ba..d0c9f17d 100644 --- a/luaconf.h +++ b/luaconf.h @@ -1,5 +1,5 @@ /* -** $Id: luaconf.h,v 1.157 2011/04/29 13:56:28 roberto Exp roberto $ +** $Id: luaconf.h,v 1.158 2011/05/26 16:09:40 roberto Exp roberto $ ** Configuration file for Lua ** See Copyright Notice in lua.h */ @@ -465,11 +465,11 @@ /* @@ LUA_IEEEENDIAN is the endianness of doubles in your machine -@@ (0 for little endian, 1 for big endian); if not defined, Lua will -@@ check it dynamically. +** (0 for little endian, 1 for big endian); if not defined, Lua will +** check it dynamically. */ /* check for known architectures */ -#if defined(__i386__) || defined(__i386) || defined(i386) || \ +#if defined(__i386__) || defined(__i386) || defined(__X86__) || \ defined (__x86_64) #define LUA_IEEEENDIAN 0 #elif defined(__POWERPC__) || defined(__ppc__) @@ -485,6 +485,30 @@ /* }================================================================== */ +/* +@@ LUA_NANTRICKLE/LUA_NANTRICKBE controls the use of a trick to pack all +** types into a single double value, using NaN values to represent +** non-number values. The trick only works on 32-bit machines (ints and +** pointers are 32-bit values) with numbers represented as IEEE 754-2008 +** doubles with conventional endianess (12345678 or 87654321), in CPUs +** that do not produce signaling NaN values (all NaNs are quiet). +*/ +#if defined(LUA_CORE) /* { */ + +#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */ + +/* little-endian architectures that satisfy those conditions */ +#if defined(__i386__) || defined(__i386) || defined(__X86__) + +#define LUA_NANTRICKLE + +#endif + +#endif /* } */ + +#endif /* } */ + + /* =================================================================== */