commit 99b1b8e9186c05cc02385b943bc0570426b0f19e
parent 3b44821334a1aa387c13eaf3cd23a2344091cbc7
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Tue, 7 Jun 2011 16:02:09 -0300
first version with 'NANTRICK' (packing all Lua values inside a 'double')
Diffstat:
M | lobject.h | | | 118 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------- |
1 file changed, 103 insertions(+), 15 deletions(-)
diff --git a/lobject.h b/lobject.h
@@ -1,5 +1,5 @@
/*
-** $Id: lobject.h,v 2.56 2011/05/31 19:15:01 roberto Exp roberto $
+** $Id: lobject.h,v 2.57 2011/06/02 19:31:40 roberto Exp roberto $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
@@ -81,13 +81,10 @@ typedef struct GCheader {
/*
** Union of all Lua values
*/
-typedef union {
- GCObject *gc; /* collectable objects */
- void *p; /* light userdata */
- lua_Number n; /* numbers */
- int b; /* booleans */
- lua_CFunction f; /* light C functions */
-} Value;
+typedef union Value Value;
+
+
+#define numfield lua_Number n; /* numbers */
@@ -98,13 +95,11 @@ typedef union {
#define TValuefields Value value_; int tt_
-typedef struct lua_TValue {
- TValuefields;
-} TValue;
+typedef struct lua_TValue TValue;
/* macro defining a nil value */
-#define NILCONSTANT {NULL}, LUA_TNIL
+#define NILCONSTANT {NULL}, LUA_TNIL
#define val_(o) ((o)->value_)
@@ -167,8 +162,8 @@ typedef struct lua_TValue {
#define righttt(obj) (ttypenv(obj) == gcvalue(obj)->gch.tt)
#define checkliveness(g,obj) \
- lua_longassert(!iscollectable(obj) || \
- (righttt(obj) && !isdead(g,gcvalue(obj))))
+ lua_longassert(!iscollectable(obj) || \
+ (righttt(obj) && !isdead(g,gcvalue(obj))))
/* Macros to set values */
@@ -177,7 +172,7 @@ typedef struct lua_TValue {
#define setnvalue(obj,x) \
{ TValue *io=(obj); num_(io)=(x); settt_(io, LUA_TNUMBER); }
-#define changenvalue(o,x) check_exp(ttisnumber(o), num_(o)=(x))
+#define changenvalue(o,x) check_exp(ttisnumber(o), num_(o)=(x))
#define setnilvalue(obj) settt_(obj, LUA_TNIL)
@@ -260,9 +255,102 @@ typedef struct lua_TValue {
+
+/*
+** {======================================================
+** NaN Trick
+** =======================================================
+*/
+
+#if defined(LUA_NANTRICK)
+
+/*
+** numbers are represented in the 'd_' field. All other values have the
+** value (0x7ff70000 | tag) in 'tt_'. A number with such pattern would be
+** a "signaled NaN", which is never generated by regular operations by
+** the CPU (nor by 'strtod')
+*/
+#undef TValuefields
+#define TValuefields \
+ union { struct { Value v_; int tt_; } i; double d_; } u
+
+#undef numfield
+#define numfield /* no such field; numbers are the entire struct */
+
+/* basic check to distinguish numbers from non-numbers */
+#undef ttisnumber
+#define ttisnumber(o) (((o)->u.i.tt_ & 0x7fff0000) != 0x7ff70000)
+
+#define tag2tt(t) (0x7ff70000 | (t))
+
+#undef NILCONSTANT
+#define NILCONSTANT {{{NULL}, tag2tt(LUA_TNIL)}}
+
+#undef val_
+#define val_(o) ((o)->u.i.v_)
+#undef num_
+#define num_(o) ((o)->u.d_)
+
+#undef rttype
+#define rttype(o) (ttisnumber(o) ? LUA_TNUMBER : (o)->u.i.tt_ & 0xff)
+
+#undef settt_
+#define settt_(o,t) ((o)->u.i.tt_=tag2tt(t))
+
+#undef setnvalue
+#define setnvalue(obj,x) \
+ { TValue *io_=(obj); num_(io_)=(x); lua_assert(ttisnumber(io_)); }
+
+#undef setobj
+#define setobj(L,obj1,obj2) \
+ { const TValue *o2_=(obj2); TValue *o1_=(obj1); \
+ o1_->u = o2_->u; \
+ checkliveness(G(L),o1_); }
+
+
+/*
+** these redefinitions are not mandatory, but these forms are more efficient
+*/
+
+#undef checktag
+#define checktag(o,t) ((o)->u.i.tt_ == tag2tt(t))
+
+#undef ttisequal
+#define ttisequal(o1,o2) \
+ (ttisnumber(o1) ? ttisnumber(o2) : ((o1)->u.i.tt_ == (o2)->u.i.tt_))
+
+
+#endif
+/* }====================================================== */
+
+
+
+/*
+** {======================================================
+** types and prototypes
+** =======================================================
+*/
+
+
+union Value {
+ GCObject *gc; /* collectable objects */
+ void *p; /* light userdata */
+ int b; /* booleans */
+ lua_CFunction f; /* light C functions */
+ numfield /* numbers */
+};
+
+
+struct lua_TValue {
+ TValuefields;
+};
+
+
typedef TValue *StkId; /* index to stack elements */
+
+
/*
** Header for string value; string bytes follow the end of this structure
*/