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

This commit is contained in:
Roberto Ierusalimschy 2011-06-07 16:02:33 -03:00
parent 3b44821334
commit 99b1b8e918

118
lobject.h
View File

@ -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
*/