aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c30
-rw-r--r--lgc.c58
-rw-r--r--llex.c4
-rw-r--r--lobject.h30
-rw-r--r--ltable.c63
-rw-r--r--ltable.h7
-rw-r--r--ltests.c6
-rw-r--r--ltm.c8
-rw-r--r--ltm.h8
-rw-r--r--lvm.c21
-rw-r--r--lvm.h10
11 files changed, 146 insertions, 99 deletions
diff --git a/lapi.c b/lapi.c
index 78ae7e0b..0debc1d3 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 2.283 2018/02/05 17:10:52 roberto Exp roberto $ 2** $Id: lapi.c,v 2.285 2018/02/20 16:52:50 roberto Exp roberto $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -657,14 +657,26 @@ LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
657} 657}
658 658
659 659
660static int finishrawget (lua_State *L, const TValue *val) {
661 if (isempty(val)) /* avoid copying empty items to the stack */
662 setnilvalue(s2v(L->top));
663 else
664 setobj2s(L, L->top, val);
665 api_incr_top(L);
666 lua_unlock(L);
667 return ttnov(s2v(L->top - 1));
668}
669
670
660LUA_API int lua_rawget (lua_State *L, int idx) { 671LUA_API int lua_rawget (lua_State *L, int idx) {
661 TValue *t; 672 TValue *t;
673 const TValue *val;
662 lua_lock(L); 674 lua_lock(L);
663 t = index2value(L, idx); 675 t = index2value(L, idx);
664 api_check(L, ttistable(t), "table expected"); 676 api_check(L, ttistable(t), "table expected");
665 setobj2s(L, L->top - 1, luaH_get(hvalue(t), s2v(L->top - 1))); 677 val = luaH_get(hvalue(t), s2v(L->top - 1));
666 lua_unlock(L); 678 L->top--; /* remove key */
667 return ttnov(s2v(L->top - 1)); 679 return finishrawget(L, val);
668} 680}
669 681
670 682
@@ -673,10 +685,7 @@ LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) {
673 lua_lock(L); 685 lua_lock(L);
674 t = index2value(L, idx); 686 t = index2value(L, idx);
675 api_check(L, ttistable(t), "table expected"); 687 api_check(L, ttistable(t), "table expected");
676 setobj2s(L, L->top, luaH_getint(hvalue(t), n)); 688 return finishrawget(L, luaH_getint(hvalue(t), n));
677 api_incr_top(L);
678 lua_unlock(L);
679 return ttnov(s2v(L->top - 1));
680} 689}
681 690
682 691
@@ -687,10 +696,7 @@ LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
687 t = index2value(L, idx); 696 t = index2value(L, idx);
688 api_check(L, ttistable(t), "table expected"); 697 api_check(L, ttistable(t), "table expected");
689 setpvalue(&k, cast_voidp(p)); 698 setpvalue(&k, cast_voidp(p));
690 setobj2s(L, L->top, luaH_get(hvalue(t), &k)); 699 return finishrawget(L, luaH_get(hvalue(t), &k));
691 api_incr_top(L);
692 lua_unlock(L);
693 return ttnov(s2v(L->top - 1));
694} 700}
695 701
696 702
diff --git a/lgc.c b/lgc.c
index 7cb3c18d..8245dc21 100644
--- a/lgc.c
+++ b/lgc.c
@@ -145,12 +145,13 @@ static GCObject **getgclist (GCObject *o) {
145** Clear keys for empty entries in tables. If entry is empty 145** Clear keys for empty entries in tables. If entry is empty
146** and its key is not marked, mark its entry as dead. This allows the 146** and its key is not marked, mark its entry as dead. This allows the
147** collection of the key, but keeps its entry in the table (its removal 147** collection of the key, but keeps its entry in the table (its removal
148** could break a chain). Other places never manipulate dead keys, 148** could break a chain). The main feature of a dead key is that it must
149** because its associated nil value is enough to signal that the entry 149** be different from any other value, to do not disturb searches.
150** is logically empty. 150** Other places never manipulate dead keys, because its associated empty
151** value is enough to signal that the entry is logically empty.
151*/ 152*/
152static void removeentry (Node *n) { 153static void clearkey (Node *n) {
153 lua_assert(ttisnil(gval(n))); 154 lua_assert(isempty(gval(n)));
154 if (keyiswhite(n)) 155 if (keyiswhite(n))
155 setdeadkey(n); /* unused and unmarked key; remove it */ 156 setdeadkey(n); /* unused and unmarked key; remove it */
156} 157}
@@ -386,8 +387,8 @@ static void traverseweakvalue (global_State *g, Table *h) {
386 worth traversing it now just to check) */ 387 worth traversing it now just to check) */
387 int hasclears = (h->sizearray > 0); 388 int hasclears = (h->sizearray > 0);
388 for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ 389 for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */
389 if (ttisnil(gval(n))) /* entry is empty? */ 390 if (isempty(gval(n))) /* entry is empty? */
390 removeentry(n); /* remove it */ 391 clearkey(n); /* clear its key */
391 else { 392 else {
392 lua_assert(!keyisnil(n)); 393 lua_assert(!keyisnil(n));
393 markkey(g, n); 394 markkey(g, n);
@@ -428,8 +429,8 @@ static int traverseephemeron (global_State *g, Table *h) {
428 } 429 }
429 /* traverse hash part */ 430 /* traverse hash part */
430 for (n = gnode(h, 0); n < limit; n++) { 431 for (n = gnode(h, 0); n < limit; n++) {
431 if (ttisnil(gval(n))) /* entry is empty? */ 432 if (isempty(gval(n))) /* entry is empty? */
432 removeentry(n); /* remove it */ 433 clearkey(n); /* clear its key */
433 else if (iscleared(g, gckeyN(n))) { /* key is not marked (yet)? */ 434 else if (iscleared(g, gckeyN(n))) { /* key is not marked (yet)? */
434 hasclears = 1; /* table must be cleared */ 435 hasclears = 1; /* table must be cleared */
435 if (valiswhite(gval(n))) /* value not marked yet? */ 436 if (valiswhite(gval(n))) /* value not marked yet? */
@@ -461,8 +462,8 @@ static void traversestrongtable (global_State *g, Table *h) {
461 for (i = 0; i < h->sizearray; i++) /* traverse array part */ 462 for (i = 0; i < h->sizearray; i++) /* traverse array part */
462 markvalue(g, &h->array[i]); 463 markvalue(g, &h->array[i]);
463 for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ 464 for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */
464 if (ttisnil(gval(n))) /* entry is empty? */ 465 if (isempty(gval(n))) /* entry is empty? */
465 removeentry(n); /* remove it */ 466 clearkey(n); /* clear its key */
466 else { 467 else {
467 lua_assert(!keyisnil(n)); 468 lua_assert(!keyisnil(n));
468 markkey(g, n); 469 markkey(g, n);
@@ -681,15 +682,16 @@ static void clearprotolist (global_State *g) {
681/* 682/*
682** clear entries with unmarked keys from all weaktables in list 'l' 683** clear entries with unmarked keys from all weaktables in list 'l'
683*/ 684*/
684static void clearkeys (global_State *g, GCObject *l) { 685static void clearbykeys (global_State *g, GCObject *l) {
685 for (; l; l = gco2t(l)->gclist) { 686 for (; l; l = gco2t(l)->gclist) {
686 Table *h = gco2t(l); 687 Table *h = gco2t(l);
687 Node *n, *limit = gnodelast(h); 688 Node *limit = gnodelast(h);
689 Node *n;
688 for (n = gnode(h, 0); n < limit; n++) { 690 for (n = gnode(h, 0); n < limit; n++) {
689 if (!ttisnil(gval(n)) && (iscleared(g, gckeyN(n)))) /* unmarked key? */ 691 if (isempty(gval(n))) /* is entry empty? */
690 setnilvalue(gval(n)); /* clear value */ 692 clearkey(n); /* clear its key */
691 if (ttisnil(gval(n))) /* is entry empty? */ 693 else if (iscleared(g, gckeyN(n))) /* unmarked key? */
692 removeentry(n); /* remove it from table */ 694 setempty(gval(n)); /* remove entry */
693 } 695 }
694 } 696 }
695} 697}
@@ -699,7 +701,7 @@ static void clearkeys (global_State *g, GCObject *l) {
699** clear entries with unmarked values from all weaktables in list 'l' up 701** clear entries with unmarked values from all weaktables in list 'l' up
700** to element 'f' 702** to element 'f'
701*/ 703*/
702static void clearvalues (global_State *g, GCObject *l, GCObject *f) { 704static void clearbyvalues (global_State *g, GCObject *l, GCObject *f) {
703 for (; l != f; l = gco2t(l)->gclist) { 705 for (; l != f; l = gco2t(l)->gclist) {
704 Table *h = gco2t(l); 706 Table *h = gco2t(l);
705 Node *n, *limit = gnodelast(h); 707 Node *n, *limit = gnodelast(h);
@@ -707,13 +709,13 @@ static void clearvalues (global_State *g, GCObject *l, GCObject *f) {
707 for (i = 0; i < h->sizearray; i++) { 709 for (i = 0; i < h->sizearray; i++) {
708 TValue *o = &h->array[i]; 710 TValue *o = &h->array[i];
709 if (iscleared(g, gcvalueN(o))) /* value was collected? */ 711 if (iscleared(g, gcvalueN(o))) /* value was collected? */
710 setnilvalue(o); /* remove value */ 712 setempty(o); /* remove entry */
711 } 713 }
712 for (n = gnode(h, 0); n < limit; n++) { 714 for (n = gnode(h, 0); n < limit; n++) {
713 if (iscleared(g, gcvalueN(gval(n)))) /* unmarked value? */ 715 if (iscleared(g, gcvalueN(gval(n)))) /* unmarked value? */
714 setnilvalue(gval(n)); /* clear value */ 716 setempty(gval(n)); /* remove entry */
715 if (ttisnil(gval(n))) /* is entry empty? */ 717 if (isempty(gval(n))) /* is entry empty? */
716 removeentry(n); /* remove it from table */ 718 clearkey(n); /* clear its key */
717 } 719 }
718 } 720 }
719} 721}
@@ -1372,8 +1374,8 @@ static lu_mem atomic (lua_State *L) {
1372 convergeephemerons(g); 1374 convergeephemerons(g);
1373 /* at this point, all strongly accessible objects are marked. */ 1375 /* at this point, all strongly accessible objects are marked. */
1374 /* Clear values from weak tables, before checking finalizers */ 1376 /* Clear values from weak tables, before checking finalizers */
1375 clearvalues(g, g->weak, NULL); 1377 clearbyvalues(g, g->weak, NULL);
1376 clearvalues(g, g->allweak, NULL); 1378 clearbyvalues(g, g->allweak, NULL);
1377 origweak = g->weak; origall = g->allweak; 1379 origweak = g->weak; origall = g->allweak;
1378 separatetobefnz(g, 0); /* separate objects to be finalized */ 1380 separatetobefnz(g, 0); /* separate objects to be finalized */
1379 work += markbeingfnz(g); /* mark objects that will be finalized */ 1381 work += markbeingfnz(g); /* mark objects that will be finalized */
@@ -1381,11 +1383,11 @@ static lu_mem atomic (lua_State *L) {
1381 convergeephemerons(g); 1383 convergeephemerons(g);
1382 /* at this point, all resurrected objects are marked. */ 1384 /* at this point, all resurrected objects are marked. */
1383 /* remove dead objects from weak tables */ 1385 /* remove dead objects from weak tables */
1384 clearkeys(g, g->ephemeron); /* clear keys from all ephemeron tables */ 1386 clearbykeys(g, g->ephemeron); /* clear keys from all ephemeron tables */
1385 clearkeys(g, g->allweak); /* clear keys from all 'allweak' tables */ 1387 clearbykeys(g, g->allweak); /* clear keys from all 'allweak' tables */
1386 /* clear values from resurrected weak tables */ 1388 /* clear values from resurrected weak tables */
1387 clearvalues(g, g->weak, origweak); 1389 clearbyvalues(g, g->weak, origweak);
1388 clearvalues(g, g->allweak, origall); 1390 clearbyvalues(g, g->allweak, origall);
1389 luaS_clearcache(g); 1391 luaS_clearcache(g);
1390 clearprotolist(g); 1392 clearprotolist(g);
1391 g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ 1393 g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */
diff --git a/llex.c b/llex.c
index be775146..5d5efb07 100644
--- a/llex.c
+++ b/llex.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: llex.c,v 2.98 2017/06/29 15:06:44 roberto Exp roberto $ 2** $Id: llex.c,v 2.99 2018/01/28 15:13:26 roberto Exp roberto $
3** Lexical Analyzer 3** Lexical Analyzer
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -130,7 +130,7 @@ TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
130 TString *ts = luaS_newlstr(L, str, l); /* create new string */ 130 TString *ts = luaS_newlstr(L, str, l); /* create new string */
131 setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */ 131 setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */
132 o = luaH_set(L, ls->h, s2v(L->top - 1)); 132 o = luaH_set(L, ls->h, s2v(L->top - 1));
133 if (ttisnil(o)) { /* not in use yet? */ 133 if (isempty(o)) { /* not in use yet? */
134 /* boolean value does not need GC barrier; 134 /* boolean value does not need GC barrier;
135 table is not a metatable, so it does not need to invalidate cache */ 135 table is not a metatable, so it does not need to invalidate cache */
136 setbvalue(o, 1); /* t[string] = true */ 136 setbvalue(o, 1); /* t[string] = true */
diff --git a/lobject.h b/lobject.h
index 2b65da36..c6590cf0 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 2.135 2018/02/21 16:28:12 roberto Exp roberto $ 2** $Id: lobject.h,v 2.136 2018/02/22 17:28:10 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*/
@@ -100,7 +100,7 @@ typedef struct TValue {
100#define setobj(L,obj1,obj2) \ 100#define setobj(L,obj1,obj2) \
101 { TValue *io1=(obj1); const TValue *io2=(obj2); \ 101 { TValue *io1=(obj1); const TValue *io2=(obj2); \
102 io1->value_ = io2->value_; io1->tt_ = io2->tt_; \ 102 io1->value_ = io2->value_; io1->tt_ = io2->tt_; \
103 (void)L; checkliveness(L,io1); } 103 (void)L; checkliveness(L,io1); lua_assert(!isreallyempty(io1)); }
104 104
105/* 105/*
106** different types of assignments, according to destination 106** different types of assignments, according to destination
@@ -148,6 +148,30 @@ typedef StackValue *StkId; /* index to stack elements */
148/* (address of) a fixed nil value */ 148/* (address of) a fixed nil value */
149#define luaO_nilobject (&luaO_nilobject_) 149#define luaO_nilobject (&luaO_nilobject_)
150 150
151
152/*
153** Variant tag, used only in tables to signal an empty slot
154** (which might be different from a slot containing nil)
155*/
156#define LUA_TEMPTY (LUA_TNIL | (1 << 4))
157
158#define ttisnilorempty(v) checktype((v), LUA_TNIL)
159/*
160** By default, entries with any kind of nil are considered empty
161*/
162#define isempty(v) ttisnilorempty(v)
163
164#define isreallyempty(v) checktag((v), LUA_TEMPTY)
165
166/* macro defining an empty value */
167#define EMPTYCONSTANT {NULL}, LUA_TEMPTY
168
169
170/* mark an entry as empty */
171#define setempty(v) settt_(v, LUA_TEMPTY)
172
173
174
151/* }================================================================== */ 175/* }================================================================== */
152 176
153 177
@@ -644,7 +668,7 @@ typedef struct Table {
644 668
645/* 669/*
646** Use a "nil table" to mark dead keys in a table. Those keys serve 670** Use a "nil table" to mark dead keys in a table. Those keys serve
647** only to keep space for removed entries, which may still be part of 671** to keep space for removed entries, which may still be part of
648** chains. Note that the 'keytt' does not have the BIT_ISCOLLECTABLE 672** chains. Note that the 'keytt' does not have the BIT_ISCOLLECTABLE
649** set, so these values are considered not collectable and are different 673** set, so these values are considered not collectable and are different
650** from any valid value. 674** from any valid value.
diff --git a/ltable.c b/ltable.c
index 5378e31a..c71d627a 100644
--- a/ltable.c
+++ b/ltable.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.c,v 2.132 2018/02/19 20:06:56 roberto Exp roberto $ 2** $Id: ltable.c,v 2.133 2018/02/21 12:54:26 roberto Exp roberto $
3** Lua tables (hash) 3** Lua tables (hash)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -88,11 +88,14 @@
88#define dummynode (&dummynode_) 88#define dummynode (&dummynode_)
89 89
90static const Node dummynode_ = { 90static const Node dummynode_ = {
91 {{NULL}, LUA_TNIL, /* value's value and type */ 91 {{NULL}, LUA_TEMPTY, /* value's value and type */
92 LUA_TNIL, 0, {NULL}} /* key type, next, and key value */ 92 LUA_TNIL, 0, {NULL}} /* key type, next, and key value */
93}; 93};
94 94
95 95
96LUAI_DDEF const TValue luaH_emptyobject_ = {EMPTYCONSTANT};
97
98
96/* 99/*
97** Hash for floating-point numbers. 100** Hash for floating-point numbers.
98** The main computation should be just 101** The main computation should be just
@@ -200,7 +203,7 @@ static const TValue *getgeneric (Table *t, const TValue *key) {
200 else { 203 else {
201 int nx = gnext(n); 204 int nx = gnext(n);
202 if (nx == 0) 205 if (nx == 0)
203 return luaO_nilobject; /* not found */ 206 return luaH_emptyobject; /* not found */
204 n += nx; 207 n += nx;
205 } 208 }
206 } 209 }
@@ -232,7 +235,7 @@ static unsigned int findindex (lua_State *L, Table *t, TValue *key) {
232 return i; /* yes; that's the index */ 235 return i; /* yes; that's the index */
233 else { 236 else {
234 const TValue *n = getgeneric(t, key); 237 const TValue *n = getgeneric(t, key);
235 if (n == luaO_nilobject) 238 if (n == luaH_emptyobject)
236 luaG_runerror(L, "invalid key to 'next'"); /* key not found */ 239 luaG_runerror(L, "invalid key to 'next'"); /* key not found */
237 i = cast_int(nodefromval(n) - gnode(t, 0)); /* key index in hash table */ 240 i = cast_int(nodefromval(n) - gnode(t, 0)); /* key index in hash table */
238 /* hash elements are numbered after array ones */ 241 /* hash elements are numbered after array ones */
@@ -244,14 +247,14 @@ static unsigned int findindex (lua_State *L, Table *t, TValue *key) {
244int luaH_next (lua_State *L, Table *t, StkId key) { 247int luaH_next (lua_State *L, Table *t, StkId key) {
245 unsigned int i = findindex(L, t, s2v(key)); /* find original element */ 248 unsigned int i = findindex(L, t, s2v(key)); /* find original element */
246 for (; i < t->sizearray; i++) { /* try first array part */ 249 for (; i < t->sizearray; i++) { /* try first array part */
247 if (!ttisnil(&t->array[i])) { /* a non-nil value? */ 250 if (!isempty(&t->array[i])) { /* a non-empty entry? */
248 setivalue(s2v(key), i + 1); 251 setivalue(s2v(key), i + 1);
249 setobj2s(L, key + 1, &t->array[i]); 252 setobj2s(L, key + 1, &t->array[i]);
250 return 1; 253 return 1;
251 } 254 }
252 } 255 }
253 for (i -= t->sizearray; cast_int(i) < sizenode(t); i++) { /* hash part */ 256 for (i -= t->sizearray; cast_int(i) < sizenode(t); i++) { /* hash part */
254 if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ 257 if (!isempty(gval(gnode(t, i)))) { /* a non-empty entry? */
255 Node *n = gnode(t, i); 258 Node *n = gnode(t, i);
256 getnodekey(L, s2v(key), n); 259 getnodekey(L, s2v(key), n);
257 setobj2s(L, key + 1, gval(n)); 260 setobj2s(L, key + 1, gval(n));
@@ -336,7 +339,7 @@ static unsigned int numusearray (const Table *t, unsigned int *nums) {
336 } 339 }
337 /* count elements in range (2^(lg - 1), 2^lg] */ 340 /* count elements in range (2^(lg - 1), 2^lg] */
338 for (; i <= lim; i++) { 341 for (; i <= lim; i++) {
339 if (!ttisnil(&t->array[i-1])) 342 if (!isempty(&t->array[i-1]))
340 lc++; 343 lc++;
341 } 344 }
342 nums[lg] += lc; 345 nums[lg] += lc;
@@ -352,7 +355,7 @@ static int numusehash (const Table *t, unsigned int *nums, unsigned int *pna) {
352 int i = sizenode(t); 355 int i = sizenode(t);
353 while (i--) { 356 while (i--) {
354 Node *n = &t->node[i]; 357 Node *n = &t->node[i];
355 if (!ttisnil(gval(n))) { 358 if (!isempty(gval(n))) {
356 if (keyisinteger(n)) 359 if (keyisinteger(n))
357 ause += countint(keyival(n), nums); 360 ause += countint(keyival(n), nums);
358 totaluse++; 361 totaluse++;
@@ -387,7 +390,7 @@ static void setnodevector (lua_State *L, Table *t, unsigned int size) {
387 Node *n = gnode(t, i); 390 Node *n = gnode(t, i);
388 gnext(n) = 0; 391 gnext(n) = 0;
389 setnilkey(n); 392 setnilkey(n);
390 setnilvalue(gval(n)); 393 setempty(gval(n));
391 } 394 }
392 t->lsizenode = cast_byte(lsize); 395 t->lsizenode = cast_byte(lsize);
393 t->lastfree = gnode(t, size); /* all positions are free */ 396 t->lastfree = gnode(t, size); /* all positions are free */
@@ -403,7 +406,7 @@ static void reinsert (lua_State *L, Table *ot, Table *t) {
403 int size = sizenode(ot); 406 int size = sizenode(ot);
404 for (j = 0; j < size; j++) { 407 for (j = 0; j < size; j++) {
405 Node *old = gnode(ot, j); 408 Node *old = gnode(ot, j);
406 if (!ttisnil(gval(old))) { 409 if (!isempty(gval(old))) {
407 /* doesn't need barrier/invalidate cache, as entry was 410 /* doesn't need barrier/invalidate cache, as entry was
408 already present in the table */ 411 already present in the table */
409 TValue k; 412 TValue k;
@@ -456,7 +459,7 @@ void luaH_resize (lua_State *L, Table *t, unsigned int newasize,
456 exchangehashpart(t, &newt); /* and new hash */ 459 exchangehashpart(t, &newt); /* and new hash */
457 /* re-insert into the new hash the elements from vanishing slice */ 460 /* re-insert into the new hash the elements from vanishing slice */
458 for (i = newasize; i < oldasize; i++) { 461 for (i = newasize; i < oldasize; i++) {
459 if (!ttisnil(&t->array[i])) 462 if (!isempty(&t->array[i]))
460 luaH_setint(L, t, i + 1, &t->array[i]); 463 luaH_setint(L, t, i + 1, &t->array[i]);
461 } 464 }
462 t->sizearray = oldasize; /* restore current size... */ 465 t->sizearray = oldasize; /* restore current size... */
@@ -473,7 +476,7 @@ void luaH_resize (lua_State *L, Table *t, unsigned int newasize,
473 t->array = newarray; /* set new array part */ 476 t->array = newarray; /* set new array part */
474 t->sizearray = newasize; 477 t->sizearray = newasize;
475 for (i = oldasize; i < newasize; i++) /* clear new slice of the array */ 478 for (i = oldasize; i < newasize; i++) /* clear new slice of the array */
476 setnilvalue(&t->array[i]); 479 setempty(&t->array[i]);
477 /* re-insert elements from old hash part into new parts */ 480 /* re-insert elements from old hash part into new parts */
478 reinsert(L, &newt, t); /* 'newt' now has the old hash */ 481 reinsert(L, &newt, t); /* 'newt' now has the old hash */
479 freehash(L, &newt); /* free old hash part */ 482 freehash(L, &newt); /* free old hash part */
@@ -569,7 +572,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
569 luaG_runerror(L, "table index is NaN"); 572 luaG_runerror(L, "table index is NaN");
570 } 573 }
571 mp = mainpositionTV(t, key); 574 mp = mainpositionTV(t, key);
572 if (!ttisnil(gval(mp)) || isdummy(t)) { /* main position is taken? */ 575 if (!isempty(gval(mp)) || isdummy(t)) { /* main position is taken? */
573 Node *othern; 576 Node *othern;
574 Node *f = getfreepos(t); /* get a free place */ 577 Node *f = getfreepos(t); /* get a free place */
575 if (f == NULL) { /* cannot find a free place? */ 578 if (f == NULL) { /* cannot find a free place? */
@@ -589,7 +592,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
589 gnext(f) += cast_int(mp - f); /* correct 'next' */ 592 gnext(f) += cast_int(mp - f); /* correct 'next' */
590 gnext(mp) = 0; /* now 'mp' is free */ 593 gnext(mp) = 0; /* now 'mp' is free */
591 } 594 }
592 setnilvalue(gval(mp)); 595 setempty(gval(mp));
593 } 596 }
594 else { /* colliding node is in its own main position */ 597 else { /* colliding node is in its own main position */
595 /* new node will go into free position */ 598 /* new node will go into free position */
@@ -602,7 +605,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
602 } 605 }
603 setnodekey(L, mp, key); 606 setnodekey(L, mp, key);
604 luaC_barrierback(L, obj2gco(t), key); 607 luaC_barrierback(L, obj2gco(t), key);
605 lua_assert(ttisnil(gval(mp))); 608 lua_assert(isempty(gval(mp)));
606 return gval(mp); 609 return gval(mp);
607} 610}
608 611
@@ -625,7 +628,7 @@ const TValue *luaH_getint (Table *t, lua_Integer key) {
625 n += nx; 628 n += nx;
626 } 629 }
627 } 630 }
628 return luaO_nilobject; 631 return luaH_emptyobject;
629 } 632 }
630} 633}
631 634
@@ -642,7 +645,7 @@ const TValue *luaH_getshortstr (Table *t, TString *key) {
642 else { 645 else {
643 int nx = gnext(n); 646 int nx = gnext(n);
644 if (nx == 0) 647 if (nx == 0)
645 return luaO_nilobject; /* not found */ 648 return luaH_emptyobject; /* not found */
646 n += nx; 649 n += nx;
647 } 650 }
648 } 651 }
@@ -667,7 +670,7 @@ const TValue *luaH_get (Table *t, const TValue *key) {
667 switch (ttype(key)) { 670 switch (ttype(key)) {
668 case LUA_TSHRSTR: return luaH_getshortstr(t, tsvalue(key)); 671 case LUA_TSHRSTR: return luaH_getshortstr(t, tsvalue(key));
669 case LUA_TNUMINT: return luaH_getint(t, ivalue(key)); 672 case LUA_TNUMINT: return luaH_getint(t, ivalue(key));
670 case LUA_TNIL: return luaO_nilobject; 673 case LUA_TNIL: return luaH_emptyobject;
671 case LUA_TNUMFLT: { 674 case LUA_TNUMFLT: {
672 lua_Integer k; 675 lua_Integer k;
673 if (luaV_flttointeger(fltvalue(key), &k, 0)) /* index is an integral? */ 676 if (luaV_flttointeger(fltvalue(key), &k, 0)) /* index is an integral? */
@@ -686,7 +689,7 @@ const TValue *luaH_get (Table *t, const TValue *key) {
686*/ 689*/
687TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { 690TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
688 const TValue *p = luaH_get(t, key); 691 const TValue *p = luaH_get(t, key);
689 if (p != luaO_nilobject) 692 if (p != luaH_emptyobject)
690 return cast(TValue *, p); 693 return cast(TValue *, p);
691 else return luaH_newkey(L, t, key); 694 else return luaH_newkey(L, t, key);
692} 695}
@@ -695,7 +698,7 @@ TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
695void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) { 698void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) {
696 const TValue *p = luaH_getint(t, key); 699 const TValue *p = luaH_getint(t, key);
697 TValue *cell; 700 TValue *cell;
698 if (p != luaO_nilobject) 701 if (p != luaH_emptyobject)
699 cell = cast(TValue *, p); 702 cell = cast(TValue *, p);
700 else { 703 else {
701 TValue k; 704 TValue k;
@@ -728,16 +731,16 @@ static lua_Unsigned hash_search (Table *t, lua_Unsigned j) {
728 j *= 2; 731 j *= 2;
729 else { 732 else {
730 j = LUA_MAXINTEGER; 733 j = LUA_MAXINTEGER;
731 if (ttisnil(luaH_getint(t, j))) /* t[j] == nil? */ 734 if (isempty(luaH_getint(t, j))) /* t[j] not present? */
732 break; /* 'j' now is an absent index */ 735 break; /* 'j' now is an absent index */
733 else /* weird case */ 736 else /* weird case */
734 return j; /* well, max integer is a boundary... */ 737 return j; /* well, max integer is a boundary... */
735 } 738 }
736 } while (!ttisnil(luaH_getint(t, j))); /* repeat until t[j] == nil */ 739 } while (!isempty(luaH_getint(t, j))); /* repeat until an absent t[j] */
737 /* i < j && t[i] !≃ nil && t[j] == nil */ 740 /* i < j && t[i] present && t[j] absent */
738 while (j - i > 1u) { /* do a binary search between them */ 741 while (j - i > 1u) { /* do a binary search between them */
739 lua_Unsigned m = (i + j) / 2; 742 lua_Unsigned m = (i + j) / 2;
740 if (ttisnil(luaH_getint(t, m))) j = m; 743 if (isempty(luaH_getint(t, m))) j = m;
741 else i = m; 744 else i = m;
742 } 745 }
743 return i; 746 return i;
@@ -746,27 +749,27 @@ static lua_Unsigned hash_search (Table *t, lua_Unsigned j) {
746 749
747/* 750/*
748** Try to find a boundary in table 't'. (A 'boundary' is an integer index 751** Try to find a boundary in table 't'. (A 'boundary' is an integer index
749** such that t[i] is non-nil and t[i+1] is nil, plus 0 if t[1] is nil 752** such that t[i] is present and t[i+1] is absent, or 0 if t[1] is absent
750** and 'maxinteger' if t[maxinteger] is not nil.) 753** and 'maxinteger' if t[maxinteger] is present.)
751** First, try the array part: if there is an array part and its last 754** First, try the array part: if there is an array part and its last
752** element is nil, there must be a boundary there; a binary search 755** element is absent, there must be a boundary there; a binary search
753** finds that boundary. Otherwise, if the hash part is empty or does not 756** finds that boundary. Otherwise, if the hash part is empty or does not
754** contain 'j + 1', 'j' is a boundary. Otherwize, call 'hash_search' 757** contain 'j + 1', 'j' is a boundary. Otherwize, call 'hash_search'
755** to find a boundary in the hash part. 758** to find a boundary in the hash part.
756*/ 759*/
757lua_Unsigned luaH_getn (Table *t) { 760lua_Unsigned luaH_getn (Table *t) {
758 unsigned int j = t->sizearray; 761 unsigned int j = t->sizearray;
759 if (j > 0 && ttisnil(&t->array[j - 1])) { 762 if (j > 0 && isempty(&t->array[j - 1])) {
760 unsigned int i = 0; 763 unsigned int i = 0;
761 while (j - i > 1u) { /* binary search */ 764 while (j - i > 1u) { /* binary search */
762 unsigned int m = (i + j) / 2; 765 unsigned int m = (i + j) / 2;
763 if (ttisnil(&t->array[m - 1])) j = m; 766 if (isempty(&t->array[m - 1])) j = m;
764 else i = m; 767 else i = m;
765 } 768 }
766 return i; 769 return i;
767 } 770 }
768 else { /* 'j' is zero or present in table */ 771 else { /* 'j' is zero or present in table */
769 if (isdummy(t) || ttisnil(luaH_getint(t, l_castU2S(j + 1)))) 772 if (isdummy(t) || isempty(luaH_getint(t, l_castU2S(j + 1))))
770 return j; /* 'j + 1' is absent... */ 773 return j; /* 'j + 1' is absent... */
771 else /* 'j + 1' is also present */ 774 else /* 'j + 1' is also present */
772 return hash_search(t, j); 775 return hash_search(t, j);
diff --git a/ltable.h b/ltable.h
index 88f90636..bcf92984 100644
--- a/ltable.h
+++ b/ltable.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.h,v 2.24 2017/05/19 12:48:15 roberto Exp roberto $ 2** $Id: ltable.h,v 2.25 2017/06/09 16:48:44 roberto Exp roberto $
3** Lua tables (hash) 3** Lua tables (hash)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -21,6 +21,8 @@
21/* true when 't' is using 'dummynode' as its hash part */ 21/* true when 't' is using 'dummynode' as its hash part */
22#define isdummy(t) ((t)->lastfree == NULL) 22#define isdummy(t) ((t)->lastfree == NULL)
23 23
24#define luaH_emptyobject (&luaH_emptyobject_)
25
24 26
25/* allocated size for hash nodes */ 27/* allocated size for hash nodes */
26#define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t)) 28#define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t))
@@ -30,6 +32,9 @@
30#define nodefromval(v) cast(Node *, (v)) 32#define nodefromval(v) cast(Node *, (v))
31 33
32 34
35LUAI_DDEC const TValue luaH_emptyobject_;
36
37
33LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); 38LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key);
34LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, 39LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key,
35 TValue *value); 40 TValue *value);
diff --git a/ltests.c b/ltests.c
index 97d1abd4..a5781fb6 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.c,v 2.240 2018/01/28 15:13:26 roberto Exp roberto $ 2** $Id: ltests.c,v 2.241 2018/02/20 16:52:50 roberto Exp roberto $
3** Internal Module for Debugging of the Lua Implementation 3** Internal Module for Debugging of the Lua Implementation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -254,7 +254,7 @@ static void checktable (global_State *g, Table *h) {
254 for (i = 0; i < h->sizearray; i++) 254 for (i = 0; i < h->sizearray; i++)
255 checkvalref(g, hgc, &h->array[i]); 255 checkvalref(g, hgc, &h->array[i]);
256 for (n = gnode(h, 0); n < limit; n++) { 256 for (n = gnode(h, 0); n < limit; n++) {
257 if (!ttisnil(gval(n))) { 257 if (!isempty(gval(n))) {
258 TValue k; 258 TValue k;
259 getnodekey(g->mainthread, &k, n); 259 getnodekey(g->mainthread, &k, n);
260 lua_assert(!keyisnil(n)); 260 lua_assert(!keyisnil(n));
@@ -842,7 +842,7 @@ static int table_query (lua_State *L) {
842 else if ((i -= t->sizearray) < sizenode(t)) { 842 else if ((i -= t->sizearray) < sizenode(t)) {
843 TValue k; 843 TValue k;
844 getnodekey(L, &k, gnode(t, i)); 844 getnodekey(L, &k, gnode(t, i));
845 if (!ttisnil(gval(gnode(t, i))) || 845 if (!isempty(gval(gnode(t, i))) ||
846 ttisnil(&k) || 846 ttisnil(&k) ||
847 ttisnumber(&k)) { 847 ttisnumber(&k)) {
848 pushobject(L, &k); 848 pushobject(L, &k);
diff --git a/ltm.c b/ltm.c
index 3f29c83b..0187c6f5 100644
--- a/ltm.c
+++ b/ltm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltm.c,v 2.62 2018/02/17 19:20:00 roberto Exp roberto $ 2** $Id: ltm.c,v 2.63 2018/02/21 15:49:32 roberto Exp roberto $
3** Tag methods 3** Tag methods
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -60,7 +60,7 @@ void luaT_init (lua_State *L) {
60const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { 60const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
61 const TValue *tm = luaH_getshortstr(events, ename); 61 const TValue *tm = luaH_getshortstr(events, ename);
62 lua_assert(event <= TM_EQ); 62 lua_assert(event <= TM_EQ);
63 if (ttisnil(tm)) { /* no tag method? */ 63 if (notm(tm)) { /* no tag method? */
64 events->flags |= cast_byte(1u<<event); /* cache this fact */ 64 events->flags |= cast_byte(1u<<event); /* cache this fact */
65 return NULL; 65 return NULL;
66 } 66 }
@@ -137,9 +137,9 @@ void luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1,
137static int callbinTM (lua_State *L, const TValue *p1, const TValue *p2, 137static int callbinTM (lua_State *L, const TValue *p1, const TValue *p2,
138 StkId res, TMS event) { 138 StkId res, TMS event) {
139 const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ 139 const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
140 if (ttisnil(tm)) 140 if (notm(tm))
141 tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ 141 tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
142 if (ttisnil(tm)) return 0; 142 if (notm(tm)) return 0;
143 luaT_callTMres(L, tm, p1, p2, res); 143 luaT_callTMres(L, tm, p1, p2, res);
144 return 1; 144 return 1;
145} 145}
diff --git a/ltm.h b/ltm.h
index dbb21bd5..9b25ef08 100644
--- a/ltm.h
+++ b/ltm.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltm.h,v 2.31 2018/02/09 15:16:06 roberto Exp roberto $ 2** $Id: ltm.h,v 2.32 2018/02/17 19:20:00 roberto Exp roberto $
3** Tag methods 3** Tag methods
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -45,6 +45,12 @@ typedef enum {
45} TMS; 45} TMS;
46 46
47 47
48/*
49** Test whether there is no tagmethod.
50** (Because tagmethods use raw accesses, the result may be an "empty" nil.)
51*/
52#define notm(tm) ttisnilorempty(tm)
53
48 54
49#define gfasttm(g,et,e) ((et) == NULL ? NULL : \ 55#define gfasttm(g,et,e) ((et) == NULL ? NULL : \
50 ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) 56 ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
diff --git a/lvm.c b/lvm.c
index efde6fb2..99e0d6b7 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.345 2018/02/21 15:49:32 roberto Exp roberto $ 2** $Id: lvm.c,v 2.346 2018/02/21 19:43:44 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -168,7 +168,7 @@ static int forlimit (const TValue *obj, lua_Integer *p, lua_Integer step,
168/* 168/*
169** Finish the table access 'val = t[key]'. 169** Finish the table access 'val = t[key]'.
170** if 'slot' is NULL, 't' is not a table; otherwise, 'slot' points to 170** if 'slot' is NULL, 't' is not a table; otherwise, 'slot' points to
171** t[k] entry (which must be nil). 171** t[k] entry (which must be empty).
172*/ 172*/
173void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val, 173void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
174 const TValue *slot) { 174 const TValue *slot) {
@@ -178,12 +178,12 @@ void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
178 if (slot == NULL) { /* 't' is not a table? */ 178 if (slot == NULL) { /* 't' is not a table? */
179 lua_assert(!ttistable(t)); 179 lua_assert(!ttistable(t));
180 tm = luaT_gettmbyobj(L, t, TM_INDEX); 180 tm = luaT_gettmbyobj(L, t, TM_INDEX);
181 if (ttisnil(tm)) 181 if (notm(tm))
182 luaG_typeerror(L, t, "index"); /* no metamethod */ 182 luaG_typeerror(L, t, "index"); /* no metamethod */
183 /* else will try the metamethod */ 183 /* else will try the metamethod */
184 } 184 }
185 else { /* 't' is a table */ 185 else { /* 't' is a table */
186 lua_assert(ttisnil(slot)); 186 lua_assert(isempty(slot));
187 tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); /* table's metamethod */ 187 tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); /* table's metamethod */
188 if (tm == NULL) { /* no metamethod? */ 188 if (tm == NULL) { /* no metamethod? */
189 setnilvalue(s2v(val)); /* result is nil */ 189 setnilvalue(s2v(val)); /* result is nil */
@@ -209,8 +209,8 @@ void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
209/* 209/*
210** Finish a table assignment 't[key] = val'. 210** Finish a table assignment 't[key] = val'.
211** If 'slot' is NULL, 't' is not a table. Otherwise, 'slot' points 211** If 'slot' is NULL, 't' is not a table. Otherwise, 'slot' points
212** to the entry 't[key]', or to 'luaO_nilobject' if there is no such 212** to the entry 't[key]', or to 'luaH_emptyobject' if there is no such
213** entry. (The value at 'slot' must be nil, otherwise 'luaV_fastget' 213** entry. (The value at 'slot' must be empty, otherwise 'luaV_fastget'
214** would have done the job.) 214** would have done the job.)
215*/ 215*/
216void luaV_finishset (lua_State *L, const TValue *t, TValue *key, 216void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
@@ -220,10 +220,10 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
220 const TValue *tm; /* '__newindex' metamethod */ 220 const TValue *tm; /* '__newindex' metamethod */
221 if (slot != NULL) { /* is 't' a table? */ 221 if (slot != NULL) { /* is 't' a table? */
222 Table *h = hvalue(t); /* save 't' table */ 222 Table *h = hvalue(t); /* save 't' table */
223 lua_assert(ttisnil(slot)); /* old value must be nil */ 223 lua_assert(isempty(slot)); /* slot must be empty */
224 tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */ 224 tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */
225 if (tm == NULL) { /* no metamethod? */ 225 if (tm == NULL) { /* no metamethod? */
226 if (slot == luaO_nilobject) /* no previous entry? */ 226 if (slot == luaH_emptyobject) /* no previous entry? */
227 slot = luaH_newkey(L, h, key); /* create one */ 227 slot = luaH_newkey(L, h, key); /* create one */
228 /* no metamethod and (now) there is an entry with given key */ 228 /* no metamethod and (now) there is an entry with given key */
229 setobj2t(L, cast(TValue *, slot), val); /* set its new value */ 229 setobj2t(L, cast(TValue *, slot), val); /* set its new value */
@@ -234,7 +234,8 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
234 /* else will try the metamethod */ 234 /* else will try the metamethod */
235 } 235 }
236 else { /* not a table; check metamethod */ 236 else { /* not a table; check metamethod */
237 if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) 237 tm = luaT_gettmbyobj(L, t, TM_NEWINDEX);
238 if (notm(tm))
238 luaG_typeerror(L, t, "index"); 239 luaG_typeerror(L, t, "index");
239 } 240 }
240 /* try the metamethod */ 241 /* try the metamethod */
@@ -586,7 +587,7 @@ void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
586 } 587 }
587 default: { /* try metamethod */ 588 default: { /* try metamethod */
588 tm = luaT_gettmbyobj(L, rb, TM_LEN); 589 tm = luaT_gettmbyobj(L, rb, TM_LEN);
589 if (ttisnil(tm)) /* no metamethod? */ 590 if (notm(tm)) /* no metamethod? */
590 luaG_typeerror(L, rb, "get length of"); 591 luaG_typeerror(L, rb, "get length of");
591 break; 592 break;
592 } 593 }
diff --git a/lvm.h b/lvm.h
index cbf7e922..c5d5206d 100644
--- a/lvm.h
+++ b/lvm.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.h,v 2.49 2018/02/19 20:06:56 roberto Exp roberto $ 2** $Id: lvm.h,v 2.50 2018/02/21 12:54:26 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -64,17 +64,17 @@
64 64
65 65
66/* 66/*
67** fast track for 'gettable': if 't' is a table and 't[k]' is not nil, 67** fast track for 'gettable': if 't' is a table and 't[k]' is present,
68** return 1 with 'slot' pointing to 't[k]' (position of final result). 68** return 1 with 'slot' pointing to 't[k]' (position of final result).
69** Otherwise, return 0 (meaning it will have to check metamethod) 69** Otherwise, return 0 (meaning it will have to check metamethod)
70** with 'slot' pointing to a nil 't[k]' (if 't' is a table) or NULL 70** with 'slot' pointing to an empty 't[k]' (if 't' is a table) or NULL
71** (otherwise). 'f' is the raw get function to use. 71** (otherwise). 'f' is the raw get function to use.
72*/ 72*/
73#define luaV_fastget(L,t,k,slot,f) \ 73#define luaV_fastget(L,t,k,slot,f) \
74 (!ttistable(t) \ 74 (!ttistable(t) \
75 ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \ 75 ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \
76 : (slot = f(hvalue(t), k), /* else, do raw access */ \ 76 : (slot = f(hvalue(t), k), /* else, do raw access */ \
77 !ttisnil(slot))) /* result not nil? */ 77 !isempty(slot))) /* result not empty? */
78 78
79 79
80/* 80/*
@@ -86,7 +86,7 @@
86 ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \ 86 ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \
87 : (slot = (l_castS2U(k) - 1u < hvalue(t)->sizearray) \ 87 : (slot = (l_castS2U(k) - 1u < hvalue(t)->sizearray) \
88 ? &hvalue(t)->array[k - 1] : luaH_getint(hvalue(t), k), \ 88 ? &hvalue(t)->array[k - 1] : luaH_getint(hvalue(t), k), \
89 !ttisnil(slot))) /* result not nil? */ 89 !isempty(slot))) /* result not empty? */
90 90
91 91
92/* 92/*