diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-06-09 13:48:44 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-06-09 13:48:44 -0300 |
commit | b6f87491afe32140563fe3c546b8812c28a63410 (patch) | |
tree | ac85dff5a850c5d488f1efa4ea95d0d7da99be16 /lobject.h | |
parent | 4bb30f461b146e1d189ee301472953e948699acf (diff) | |
download | lua-b6f87491afe32140563fe3c546b8812c28a63410.tar.gz lua-b6f87491afe32140563fe3c546b8812c28a63410.tar.bz2 lua-b6f87491afe32140563fe3c546b8812c28a63410.zip |
in hash nodes, keys are stored in separate pieces to avoid wasting
space with alignments
Diffstat (limited to 'lobject.h')
-rw-r--r-- | lobject.h | 98 |
1 files changed, 76 insertions, 22 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lobject.h,v 2.120 2017/04/30 20:43:26 roberto Exp roberto $ | 2 | ** $Id: lobject.h,v 2.121 2017/06/01 20:24:05 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 | */ |
@@ -122,6 +122,7 @@ typedef struct lua_TValue { | |||
122 | 122 | ||
123 | 123 | ||
124 | #define val_(o) ((o)->value_) | 124 | #define val_(o) ((o)->value_) |
125 | #define valraw(o) (&val_(o)) | ||
125 | 126 | ||
126 | 127 | ||
127 | /* raw type tag of a TValue */ | 128 | /* raw type tag of a TValue */ |
@@ -131,7 +132,8 @@ typedef struct lua_TValue { | |||
131 | #define novariant(x) ((x) & 0x0F) | 132 | #define novariant(x) ((x) & 0x0F) |
132 | 133 | ||
133 | /* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */ | 134 | /* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */ |
134 | #define ttype(o) (rttype(o) & 0x3F) | 135 | #define ttyperaw(t) ((t) & 0x3F) |
136 | #define ttype(o) ttyperaw(rttype(o)) | ||
135 | 137 | ||
136 | /* type tag of a TValue with no variants (bits 0-3) */ | 138 | /* type tag of a TValue with no variants (bits 0-3) */ |
137 | #define ttnov(o) (novariant(rttype(o))) | 139 | #define ttnov(o) (novariant(rttype(o))) |
@@ -157,7 +159,19 @@ typedef struct lua_TValue { | |||
157 | #define ttislcf(o) checktag((o), LUA_TLCF) | 159 | #define ttislcf(o) checktag((o), LUA_TLCF) |
158 | #define ttisfulluserdata(o) checktag((o), ctb(LUA_TUSERDATA)) | 160 | #define ttisfulluserdata(o) checktag((o), ctb(LUA_TUSERDATA)) |
159 | #define ttisthread(o) checktag((o), ctb(LUA_TTHREAD)) | 161 | #define ttisthread(o) checktag((o), ctb(LUA_TTHREAD)) |
160 | #define ttisdeadkey(o) checktag((o), LUA_TDEADKEY) | 162 | |
163 | |||
164 | /* | ||
165 | ** Macros to access unstructured values (may come both from | ||
166 | ** 'TValue's and table keys) | ||
167 | */ | ||
168 | #define ivalueraw(v) ((v).i) | ||
169 | #define fltvalueraw(v) ((v).n) | ||
170 | #define gcvalueraw(v) ((v).gc) | ||
171 | #define pvalueraw(v) ((v).p) | ||
172 | #define tsvalueraw(v) (gco2ts((v).gc)) | ||
173 | #define fvalueraw(v) ((v).f) | ||
174 | #define bvalueraw(v) ((v).b) | ||
161 | 175 | ||
162 | 176 | ||
163 | /* Macros to access values */ | 177 | /* Macros to access values */ |
@@ -176,8 +190,6 @@ typedef struct lua_TValue { | |||
176 | #define hvalue(o) check_exp(ttistable(o), gco2t(val_(o).gc)) | 190 | #define hvalue(o) check_exp(ttistable(o), gco2t(val_(o).gc)) |
177 | #define bvalue(o) check_exp(ttisboolean(o), val_(o).b) | 191 | #define bvalue(o) check_exp(ttisboolean(o), val_(o).b) |
178 | #define thvalue(o) check_exp(ttisthread(o), gco2th(val_(o).gc)) | 192 | #define thvalue(o) check_exp(ttisthread(o), gco2th(val_(o).gc)) |
179 | /* a dead value may get the 'gc' field, but cannot access its contents */ | ||
180 | #define deadvalue(o) check_exp(ttisdeadkey(o), cast(void *, val_(o).gc)) | ||
181 | 193 | ||
182 | #define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) | 194 | #define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) |
183 | 195 | ||
@@ -185,6 +197,12 @@ typedef struct lua_TValue { | |||
185 | #define iscollectable(o) (rttype(o) & BIT_ISCOLLECTABLE) | 197 | #define iscollectable(o) (rttype(o) & BIT_ISCOLLECTABLE) |
186 | 198 | ||
187 | 199 | ||
200 | /* | ||
201 | ** Protected access to objects in values | ||
202 | */ | ||
203 | #define gcvalueN(o) (iscollectable(o) ? gcvalue(o) : NULL) | ||
204 | |||
205 | |||
188 | /* Macros for internal tests */ | 206 | /* Macros for internal tests */ |
189 | #define righttt(obj) (ttype(obj) == gcvalue(obj)->tt) | 207 | #define righttt(obj) (ttype(obj) == gcvalue(obj)->tt) |
190 | 208 | ||
@@ -253,8 +271,6 @@ typedef struct lua_TValue { | |||
253 | val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TTABLE)); \ | 271 | val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TTABLE)); \ |
254 | checkliveness(L,io); } | 272 | checkliveness(L,io); } |
255 | 273 | ||
256 | #define setdeadvalue(obj) settt_(obj, LUA_TDEADKEY) | ||
257 | |||
258 | 274 | ||
259 | 275 | ||
260 | #define setobj(L,obj1,obj2) \ | 276 | #define setobj(L,obj1,obj2) \ |
@@ -485,26 +501,37 @@ typedef union Closure { | |||
485 | ** Tables | 501 | ** Tables |
486 | */ | 502 | */ |
487 | 503 | ||
488 | typedef union TKey { | 504 | |
489 | struct { | 505 | /* |
490 | TValuefields; | 506 | ** Nodes for Hash tables. A pack of two TValue's (key-value pairs) |
491 | int next; /* for chaining (offset for next node) */ | 507 | ** plus a 'next' field to link colliding entries. The distribuition |
492 | } nk; | 508 | ** of the key's fields ('key_tt' and 'key_val') not forming a proper |
493 | TValue tvk; | 509 | ** 'TValue' allows for a smaller size for 'Node' both in 4-byte |
494 | } TKey; | 510 | ** and 8-byte alignments. |
511 | */ | ||
512 | typedef union Node { | ||
513 | struct NodeKey { | ||
514 | TValuefields; /* fields for value */ | ||
515 | lu_byte key_tt; /* key type */ | ||
516 | int next; /* for chaining */ | ||
517 | Value key_val; /* key value */ | ||
518 | } u; | ||
519 | TValue i_val; /* direct access to node's value as a proper 'TValue' */ | ||
520 | } Node; | ||
495 | 521 | ||
496 | 522 | ||
497 | /* copy a value into a key without messing up field 'next' */ | 523 | /* copy a value into a key */ |
498 | #define setnodekey(L,key,obj) \ | 524 | #define setnodekey(L,node,obj) \ |
499 | { TKey *k_=(key); const TValue *io_=(obj); \ | 525 | { Node *n_=(node); const TValue *io_=(obj); \ |
500 | k_->nk.value_ = io_->value_; k_->nk.tt_ = io_->tt_; \ | 526 | n_->u.key_val = io_->value_; n_->u.key_tt = io_->tt_; \ |
501 | (void)L; checkliveness(L,io_); } | 527 | (void)L; checkliveness(L,io_); } |
502 | 528 | ||
503 | 529 | ||
504 | typedef struct Node { | 530 | /* copy a value from a key */ |
505 | TValue i_val; | 531 | #define getnodekey(L,obj,node) \ |
506 | TKey i_key; | 532 | { TValue *io_=(obj); const Node *n_=(node); \ |
507 | } Node; | 533 | io_->value_ = n_->u.key_val; io_->tt_ = n_->u.key_tt; \ |
534 | (void)L; checkliveness(L,io_); } | ||
508 | 535 | ||
509 | 536 | ||
510 | typedef struct Table { | 537 | typedef struct Table { |
@@ -520,6 +547,33 @@ typedef struct Table { | |||
520 | } Table; | 547 | } Table; |
521 | 548 | ||
522 | 549 | ||
550 | /* | ||
551 | ** Macros to manipulate keys inserted in nodes | ||
552 | */ | ||
553 | #define keytt(node) ((node)->u.key_tt) | ||
554 | #define keyval(node) ((node)->u.key_val) | ||
555 | |||
556 | #define keyisnil(node) (keytt(node) == LUA_TNIL) | ||
557 | #define keyisinteger(node) (keytt(node) == LUA_TNUMINT) | ||
558 | #define keyival(node) (keyval(node).i) | ||
559 | #define keyisshrstr(node) (keytt(node) == ctb(LUA_TSHRSTR)) | ||
560 | #define keystrval(node) (gco2ts(keyval(node).gc)) | ||
561 | |||
562 | #define keyisdead(node) (keytt(node) == LUA_TDEADKEY) | ||
563 | |||
564 | #define setnilkey(node) (keytt(node) = LUA_TNIL) | ||
565 | #define setdeadkey(node) (keytt(node) = LUA_TDEADKEY) | ||
566 | |||
567 | /* a dead value may get the 'gc' field, but cannot access its contents */ | ||
568 | #define deadkey(n) \ | ||
569 | check_exp(keytt(n) == LUA_TDEADKEY, cast(void *, keyval(n).gc)) | ||
570 | |||
571 | #define keyiscollectable(n) (keytt(n) & BIT_ISCOLLECTABLE) | ||
572 | |||
573 | #define gckey(n) (keyval(n).gc) | ||
574 | #define gckeyN(n) (keyiscollectable(n) ? gckey(n) : NULL) | ||
575 | |||
576 | |||
523 | 577 | ||
524 | /* | 578 | /* |
525 | ** 'module' operation for hashing (size is always a power of 2) | 579 | ** 'module' operation for hashing (size is always a power of 2) |