diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2011-06-07 16:02:33 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2011-06-07 16:02:33 -0300 |
commit | 99b1b8e9186c05cc02385b943bc0570426b0f19e (patch) | |
tree | 826de71daa491aa7767224c6c1bd2a7e0cca95c5 | |
parent | 3b44821334a1aa387c13eaf3cd23a2344091cbc7 (diff) | |
download | lua-99b1b8e9186c05cc02385b943bc0570426b0f19e.tar.gz lua-99b1b8e9186c05cc02385b943bc0570426b0f19e.tar.bz2 lua-99b1b8e9186c05cc02385b943bc0570426b0f19e.zip |
first version with 'NANTRICK' (packing all Lua values inside a 'double')
-rw-r--r-- | lobject.h | 118 |
1 files changed, 103 insertions, 15 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lobject.h,v 2.56 2011/05/31 19:15:01 roberto Exp roberto $ | 2 | ** $Id: lobject.h,v 2.57 2011/06/02 19:31:40 roberto Exp roberto $ |
3 | ** Type definitions for Lua objects | 3 | ** Type definitions for Lua objects |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -81,13 +81,10 @@ typedef struct GCheader { | |||
81 | /* | 81 | /* |
82 | ** Union of all Lua values | 82 | ** Union of all Lua values |
83 | */ | 83 | */ |
84 | typedef union { | 84 | typedef union Value Value; |
85 | GCObject *gc; /* collectable objects */ | 85 | |
86 | void *p; /* light userdata */ | 86 | |
87 | lua_Number n; /* numbers */ | 87 | #define numfield lua_Number n; /* numbers */ |
88 | int b; /* booleans */ | ||
89 | lua_CFunction f; /* light C functions */ | ||
90 | } Value; | ||
91 | 88 | ||
92 | 89 | ||
93 | 90 | ||
@@ -98,13 +95,11 @@ typedef union { | |||
98 | 95 | ||
99 | #define TValuefields Value value_; int tt_ | 96 | #define TValuefields Value value_; int tt_ |
100 | 97 | ||
101 | typedef struct lua_TValue { | 98 | typedef struct lua_TValue TValue; |
102 | TValuefields; | ||
103 | } TValue; | ||
104 | 99 | ||
105 | 100 | ||
106 | /* macro defining a nil value */ | 101 | /* macro defining a nil value */ |
107 | #define NILCONSTANT {NULL}, LUA_TNIL | 102 | #define NILCONSTANT {NULL}, LUA_TNIL |
108 | 103 | ||
109 | 104 | ||
110 | #define val_(o) ((o)->value_) | 105 | #define val_(o) ((o)->value_) |
@@ -167,8 +162,8 @@ typedef struct lua_TValue { | |||
167 | #define righttt(obj) (ttypenv(obj) == gcvalue(obj)->gch.tt) | 162 | #define righttt(obj) (ttypenv(obj) == gcvalue(obj)->gch.tt) |
168 | 163 | ||
169 | #define checkliveness(g,obj) \ | 164 | #define checkliveness(g,obj) \ |
170 | lua_longassert(!iscollectable(obj) || \ | 165 | lua_longassert(!iscollectable(obj) || \ |
171 | (righttt(obj) && !isdead(g,gcvalue(obj)))) | 166 | (righttt(obj) && !isdead(g,gcvalue(obj)))) |
172 | 167 | ||
173 | 168 | ||
174 | /* Macros to set values */ | 169 | /* Macros to set values */ |
@@ -177,7 +172,7 @@ typedef struct lua_TValue { | |||
177 | #define setnvalue(obj,x) \ | 172 | #define setnvalue(obj,x) \ |
178 | { TValue *io=(obj); num_(io)=(x); settt_(io, LUA_TNUMBER); } | 173 | { TValue *io=(obj); num_(io)=(x); settt_(io, LUA_TNUMBER); } |
179 | 174 | ||
180 | #define changenvalue(o,x) check_exp(ttisnumber(o), num_(o)=(x)) | 175 | #define changenvalue(o,x) check_exp(ttisnumber(o), num_(o)=(x)) |
181 | 176 | ||
182 | #define setnilvalue(obj) settt_(obj, LUA_TNIL) | 177 | #define setnilvalue(obj) settt_(obj, LUA_TNIL) |
183 | 178 | ||
@@ -260,9 +255,102 @@ typedef struct lua_TValue { | |||
260 | 255 | ||
261 | 256 | ||
262 | 257 | ||
258 | |||
259 | /* | ||
260 | ** {====================================================== | ||
261 | ** NaN Trick | ||
262 | ** ======================================================= | ||
263 | */ | ||
264 | |||
265 | #if defined(LUA_NANTRICK) | ||
266 | |||
267 | /* | ||
268 | ** numbers are represented in the 'd_' field. All other values have the | ||
269 | ** value (0x7ff70000 | tag) in 'tt_'. A number with such pattern would be | ||
270 | ** a "signaled NaN", which is never generated by regular operations by | ||
271 | ** the CPU (nor by 'strtod') | ||
272 | */ | ||
273 | #undef TValuefields | ||
274 | #define TValuefields \ | ||
275 | union { struct { Value v_; int tt_; } i; double d_; } u | ||
276 | |||
277 | #undef numfield | ||
278 | #define numfield /* no such field; numbers are the entire struct */ | ||
279 | |||
280 | /* basic check to distinguish numbers from non-numbers */ | ||
281 | #undef ttisnumber | ||
282 | #define ttisnumber(o) (((o)->u.i.tt_ & 0x7fff0000) != 0x7ff70000) | ||
283 | |||
284 | #define tag2tt(t) (0x7ff70000 | (t)) | ||
285 | |||
286 | #undef NILCONSTANT | ||
287 | #define NILCONSTANT {{{NULL}, tag2tt(LUA_TNIL)}} | ||
288 | |||
289 | #undef val_ | ||
290 | #define val_(o) ((o)->u.i.v_) | ||
291 | #undef num_ | ||
292 | #define num_(o) ((o)->u.d_) | ||
293 | |||
294 | #undef rttype | ||
295 | #define rttype(o) (ttisnumber(o) ? LUA_TNUMBER : (o)->u.i.tt_ & 0xff) | ||
296 | |||
297 | #undef settt_ | ||
298 | #define settt_(o,t) ((o)->u.i.tt_=tag2tt(t)) | ||
299 | |||
300 | #undef setnvalue | ||
301 | #define setnvalue(obj,x) \ | ||
302 | { TValue *io_=(obj); num_(io_)=(x); lua_assert(ttisnumber(io_)); } | ||
303 | |||
304 | #undef setobj | ||
305 | #define setobj(L,obj1,obj2) \ | ||
306 | { const TValue *o2_=(obj2); TValue *o1_=(obj1); \ | ||
307 | o1_->u = o2_->u; \ | ||
308 | checkliveness(G(L),o1_); } | ||
309 | |||
310 | |||
311 | /* | ||
312 | ** these redefinitions are not mandatory, but these forms are more efficient | ||
313 | */ | ||
314 | |||
315 | #undef checktag | ||
316 | #define checktag(o,t) ((o)->u.i.tt_ == tag2tt(t)) | ||
317 | |||
318 | #undef ttisequal | ||
319 | #define ttisequal(o1,o2) \ | ||
320 | (ttisnumber(o1) ? ttisnumber(o2) : ((o1)->u.i.tt_ == (o2)->u.i.tt_)) | ||
321 | |||
322 | |||
323 | #endif | ||
324 | /* }====================================================== */ | ||
325 | |||
326 | |||
327 | |||
328 | /* | ||
329 | ** {====================================================== | ||
330 | ** types and prototypes | ||
331 | ** ======================================================= | ||
332 | */ | ||
333 | |||
334 | |||
335 | union Value { | ||
336 | GCObject *gc; /* collectable objects */ | ||
337 | void *p; /* light userdata */ | ||
338 | int b; /* booleans */ | ||
339 | lua_CFunction f; /* light C functions */ | ||
340 | numfield /* numbers */ | ||
341 | }; | ||
342 | |||
343 | |||
344 | struct lua_TValue { | ||
345 | TValuefields; | ||
346 | }; | ||
347 | |||
348 | |||
263 | typedef TValue *StkId; /* index to stack elements */ | 349 | typedef TValue *StkId; /* index to stack elements */ |
264 | 350 | ||
265 | 351 | ||
352 | |||
353 | |||
266 | /* | 354 | /* |
267 | ** Header for string value; string bytes follow the end of this structure | 355 | ** Header for string value; string bytes follow the end of this structure |
268 | */ | 356 | */ |