diff options
-rw-r--r-- | lapi.c | 30 | ||||
-rw-r--r-- | lgc.c | 58 | ||||
-rw-r--r-- | llex.c | 4 | ||||
-rw-r--r-- | lobject.h | 30 | ||||
-rw-r--r-- | ltable.c | 63 | ||||
-rw-r--r-- | ltable.h | 7 | ||||
-rw-r--r-- | ltests.c | 6 | ||||
-rw-r--r-- | ltm.c | 8 | ||||
-rw-r--r-- | ltm.h | 8 | ||||
-rw-r--r-- | lvm.c | 21 | ||||
-rw-r--r-- | lvm.h | 10 |
11 files changed, 146 insertions, 99 deletions
@@ -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 | ||
660 | static 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 | |||
660 | LUA_API int lua_rawget (lua_State *L, int idx) { | 671 | LUA_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 | ||
@@ -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 | */ |
152 | static void removeentry (Node *n) { | 153 | static 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 | */ |
684 | static void clearkeys (global_State *g, GCObject *l) { | 685 | static 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 | */ |
702 | static void clearvalues (global_State *g, GCObject *l, GCObject *f) { | 704 | static 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 */ |
@@ -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 */ |
@@ -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. |
@@ -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 | ||
90 | static const Node dummynode_ = { | 90 | static 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 | ||
96 | LUAI_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) { | |||
244 | int luaH_next (lua_State *L, Table *t, StkId key) { | 247 | int 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 | */ |
687 | TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { | 690 | TValue *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) { | |||
695 | void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) { | 698 | void 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 | */ |
757 | lua_Unsigned luaH_getn (Table *t) { | 760 | lua_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); |
@@ -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 | ||
35 | LUAI_DDEC const TValue luaH_emptyobject_; | ||
36 | |||
37 | |||
33 | LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); | 38 | LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); |
34 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, | 39 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, |
35 | TValue *value); | 40 | TValue *value); |
@@ -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); |
@@ -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) { | |||
60 | const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { | 60 | const 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, | |||
137 | static int callbinTM (lua_State *L, const TValue *p1, const TValue *p2, | 137 | static 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 | } |
@@ -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])) |
@@ -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 | */ |
173 | void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val, | 173 | void 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 | */ |
216 | void luaV_finishset (lua_State *L, const TValue *t, TValue *key, | 216 | void 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 | } |
@@ -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 | /* |