diff --git a/lobject.h b/lobject.h index daa46472..1d8bd64d 100644 --- 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 */