瀏覽代碼

first version with 'NANTRICK' (packing all Lua values inside a 'double')

Roberto Ierusalimschy 14 年之前
父節點
當前提交
99b1b8e918
共有 1 個文件被更改,包括 103 次插入15 次删除
  1. 103 15
      lobject.h

+ 103 - 15
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
 ** Type definitions for Lua objects
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -81,13 +81,10 @@ typedef struct GCheader {
 /*
 /*
 ** Union of all Lua values
 ** 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_
 #define TValuefields	Value value_; int tt_
 
 
-typedef struct lua_TValue {
-  TValuefields;
-} TValue;
+typedef struct lua_TValue TValue;
 
 
 
 
 /* macro defining a nil value */
 /* macro defining a nil value */
-#define NILCONSTANT    {NULL}, LUA_TNIL
+#define NILCONSTANT	{NULL}, LUA_TNIL
 
 
 
 
 #define val_(o)		((o)->value_)
 #define val_(o)		((o)->value_)
@@ -167,8 +162,8 @@ typedef struct lua_TValue {
 #define righttt(obj)		(ttypenv(obj) == gcvalue(obj)->gch.tt)
 #define righttt(obj)		(ttypenv(obj) == gcvalue(obj)->gch.tt)
 
 
 #define checkliveness(g,obj) \
 #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 */
 /* Macros to set values */
@@ -177,7 +172,7 @@ typedef struct lua_TValue {
 #define setnvalue(obj,x) \
 #define setnvalue(obj,x) \
   { TValue *io=(obj); num_(io)=(x); settt_(io, LUA_TNUMBER); }
   { 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)
 #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 */
 typedef TValue *StkId;  /* index to stack elements */
 
 
 
 
+
+
 /*
 /*
 ** Header for string value; string bytes follow the end of this structure
 ** Header for string value; string bytes follow the end of this structure
 */
 */