lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On 8 June 2015 at 14:34, Roberto Ierusalimschy <roberto@inf.puc-rio.br> wrote:
>> The various macros in lobject.h for setting value and type, checking
>> if a type is a given type, or extracting the value component from
>> TValue - these are the only ways in which Lua ever manipulates a
>> TValue object.

> There should not be hidden assumptions. BTW, Lua 5.2 has the NaN trick
> implemented (on top of these macros).

Cool, did not see that. Why was it removed in 5.3?

My implementation is similar. It does seem to work, although my
impression is performance is degraded slightly. Even in JIT mode I did
not get the hoped for improvement for operations involving numbers
(where the type is statically defined and known to the compiler).

#define RAVI_NAN_TAG   0x7ffc0000
#define RAVI_TYPE_MASK 0x0000ffff

/*
TODO This is little endian - need to switch lo/hi for big
endian
*/
typedef struct ravi_HiLo {
  int lo;
  int hi;
} HiLo;

typedef union ravi_TypeOrDouble {
  HiLo hilo;
  double n;
} TypeOrDouble;

/*
** Tagged Values. This is the basic representation of values in Lua,
** an actual value plus a tag with its type.
*/

#define TValuefields Value value_; TypeOrDouble tt_

typedef struct lua_TValue TValue;


/* macro defining a nil value */
/* TODO this is for little endian, make it work for big endian */
#define NILCONSTANT {NULL}, {0, (RAVI_NAN_TAG|LUA_TNIL)}

/* Note that numbers are not stored in value_ when NaN tagging is ON */
#define val_(o) ((o)->value_)
#define numval_(o) ((o)->tt_)

#define extracttype(o) ((o)->tt_.hilo.hi & RAVI_NAN_TAG)

/* raw type tag of a TValue */
#define rttype(o) (extracttype(o)==RAVI_NAN_TAG ? ((o)->tt_.hilo.hi &
RAVI_TYPE_MASK) : LUA_TNUMFLT)

/* Macros to test type */
#define ttisfloat(o) (extracttype(o) != RAVI_NAN_TAG)
#define ttisnumber(o) (ttisfloat(o) || ttisinteger(o))


/* Macros to access values */
#define ivalue(o) check_exp(ttisinteger(o), val_(o).i)
#define fltvalue(o) check_exp(ttisfloat(o), numval_(o).n)
#define nvalue(o) check_exp(ttisnumber(o), \
(ttisinteger(o) ? cast_num(ivalue(o)) : fltvalue(o)))

/* Macros to set values */
#define settt_(o,t) ((o)->tt_.hilo.hi=(t|RAVI_NAN_TAG))

#define setfltvalue(obj,x) \
  { TValue *io=(obj); numval_(io).n=(x); }

#define setivalue(obj,x) \
  { TValue *io=(obj); val_(io).i=(x); settt_(io, LUA_TNUMINT); }