diff options
author | Li Jin <dragon-fly@qq.com> | 2021-01-05 16:48:53 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2021-01-05 16:48:53 +0800 |
commit | 71b9532659abb531bd1597d88451426dcc895824 (patch) | |
tree | c9b50856b37f759c9a31e1a6e761e77b51996fa6 /src/lua/ltable.c | |
parent | e3a31f9945053d8e8d9e4ef3d2e4c9abe563cff2 (diff) | |
download | yuescript-71b9532659abb531bd1597d88451426dcc895824.tar.gz yuescript-71b9532659abb531bd1597d88451426dcc895824.tar.bz2 yuescript-71b9532659abb531bd1597d88451426dcc895824.zip |
update Lua.
Diffstat (limited to 'src/lua/ltable.c')
-rw-r--r-- | src/lua/ltable.c | 69 |
1 files changed, 44 insertions, 25 deletions
diff --git a/src/lua/ltable.c b/src/lua/ltable.c index 38bee1d..e9410f9 100644 --- a/src/lua/ltable.c +++ b/src/lua/ltable.c | |||
@@ -166,17 +166,24 @@ static Node *mainpositionTV (const Table *t, const TValue *key) { | |||
166 | 166 | ||
167 | 167 | ||
168 | /* | 168 | /* |
169 | ** Check whether key 'k1' is equal to the key in node 'n2'. | 169 | ** Check whether key 'k1' is equal to the key in node 'n2'. This |
170 | ** This equality is raw, so there are no metamethods. Floats | 170 | ** equality is raw, so there are no metamethods. Floats with integer |
171 | ** with integer values have been normalized, so integers cannot | 171 | ** values have been normalized, so integers cannot be equal to |
172 | ** be equal to floats. It is assumed that 'eqshrstr' is simply | 172 | ** floats. It is assumed that 'eqshrstr' is simply pointer equality, so |
173 | ** pointer equality, so that short strings are handled in the | 173 | ** that short strings are handled in the default case. |
174 | ** default case. | ||
175 | ** A true 'deadok' means to accept dead keys as equal to their original | 174 | ** A true 'deadok' means to accept dead keys as equal to their original |
176 | ** values, which can only happen if the original key was collectable. | 175 | ** values. All dead keys are compared in the default case, by pointer |
177 | ** All dead values are compared in the default case, by pointer | 176 | ** identity. (Only collectable objects can produce dead keys.) Note that |
178 | ** identity. (Note that dead long strings are also compared by | 177 | ** dead long strings are also compared by identity. |
179 | ** identity). | 178 | ** Once a key is dead, its corresponding value may be collected, and |
179 | ** then another value can be created with the same address. If this | ||
180 | ** other value is given to 'next', 'equalkey' will signal a false | ||
181 | ** positive. In a regular traversal, this situation should never happen, | ||
182 | ** as all keys given to 'next' came from the table itself, and therefore | ||
183 | ** could not have been collected. Outside a regular traversal, we | ||
184 | ** have garbage in, garbage out. What is relevant is that this false | ||
185 | ** positive does not break anything. (In particular, 'next' will return | ||
186 | ** some other valid item on the table or nil.) | ||
180 | */ | 187 | */ |
181 | static int equalkey (const TValue *k1, const Node *n2, int deadok) { | 188 | static int equalkey (const TValue *k1, const Node *n2, int deadok) { |
182 | if ((rawtt(k1) != keytt(n2)) && /* not the same variants? */ | 189 | if ((rawtt(k1) != keytt(n2)) && /* not the same variants? */ |
@@ -478,7 +485,7 @@ static void reinsert (lua_State *L, Table *ot, Table *t) { | |||
478 | already present in the table */ | 485 | already present in the table */ |
479 | TValue k; | 486 | TValue k; |
480 | getnodekey(L, &k, old); | 487 | getnodekey(L, &k, old); |
481 | setobjt2t(L, luaH_set(L, t, &k), gval(old)); | 488 | luaH_set(L, t, &k, gval(old)); |
482 | } | 489 | } |
483 | } | 490 | } |
484 | } | 491 | } |
@@ -625,7 +632,7 @@ static Node *getfreepos (Table *t) { | |||
625 | ** put new key in its main position; otherwise (colliding node is in its main | 632 | ** put new key in its main position; otherwise (colliding node is in its main |
626 | ** position), new key goes to an empty position. | 633 | ** position), new key goes to an empty position. |
627 | */ | 634 | */ |
628 | TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { | 635 | void luaH_newkey (lua_State *L, Table *t, const TValue *key, TValue *value) { |
629 | Node *mp; | 636 | Node *mp; |
630 | TValue aux; | 637 | TValue aux; |
631 | if (unlikely(ttisnil(key))) | 638 | if (unlikely(ttisnil(key))) |
@@ -647,7 +654,8 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { | |||
647 | if (f == NULL) { /* cannot find a free place? */ | 654 | if (f == NULL) { /* cannot find a free place? */ |
648 | rehash(L, t, key); /* grow table */ | 655 | rehash(L, t, key); /* grow table */ |
649 | /* whatever called 'newkey' takes care of TM cache */ | 656 | /* whatever called 'newkey' takes care of TM cache */ |
650 | return luaH_set(L, t, key); /* insert key into grown table */ | 657 | luaH_set(L, t, key, value); /* insert key into grown table */ |
658 | return; | ||
651 | } | 659 | } |
652 | lua_assert(!isdummy(t)); | 660 | lua_assert(!isdummy(t)); |
653 | othern = mainposition(t, keytt(mp), &keyval(mp)); | 661 | othern = mainposition(t, keytt(mp), &keyval(mp)); |
@@ -675,7 +683,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { | |||
675 | setnodekey(L, mp, key); | 683 | setnodekey(L, mp, key); |
676 | luaC_barrierback(L, obj2gco(t), key); | 684 | luaC_barrierback(L, obj2gco(t), key); |
677 | lua_assert(isempty(gval(mp))); | 685 | lua_assert(isempty(gval(mp))); |
678 | return gval(mp); | 686 | setobj2t(L, gval(mp), value); |
679 | } | 687 | } |
680 | 688 | ||
681 | 689 | ||
@@ -763,28 +771,39 @@ const TValue *luaH_get (Table *t, const TValue *key) { | |||
763 | 771 | ||
764 | 772 | ||
765 | /* | 773 | /* |
774 | ** Finish a raw "set table" operation, where 'slot' is where the value | ||
775 | ** should have been (the result of a previous "get table"). | ||
776 | ** Beware: when using this function you probably need to check a GC | ||
777 | ** barrier and invalidate the TM cache. | ||
778 | */ | ||
779 | void luaH_finishset (lua_State *L, Table *t, const TValue *key, | ||
780 | const TValue *slot, TValue *value) { | ||
781 | if (isabstkey(slot)) | ||
782 | luaH_newkey(L, t, key, value); | ||
783 | else | ||
784 | setobj2t(L, cast(TValue *, slot), value); | ||
785 | } | ||
786 | |||
787 | |||
788 | /* | ||
766 | ** beware: when using this function you probably need to check a GC | 789 | ** beware: when using this function you probably need to check a GC |
767 | ** barrier and invalidate the TM cache. | 790 | ** barrier and invalidate the TM cache. |
768 | */ | 791 | */ |
769 | TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { | 792 | void luaH_set (lua_State *L, Table *t, const TValue *key, TValue *value) { |
770 | const TValue *p = luaH_get(t, key); | 793 | const TValue *slot = luaH_get(t, key); |
771 | if (!isabstkey(p)) | 794 | luaH_finishset(L, t, key, slot, value); |
772 | return cast(TValue *, p); | ||
773 | else return luaH_newkey(L, t, key); | ||
774 | } | 795 | } |
775 | 796 | ||
776 | 797 | ||
777 | void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) { | 798 | void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) { |
778 | const TValue *p = luaH_getint(t, key); | 799 | const TValue *p = luaH_getint(t, key); |
779 | TValue *cell; | 800 | if (isabstkey(p)) { |
780 | if (!isabstkey(p)) | ||
781 | cell = cast(TValue *, p); | ||
782 | else { | ||
783 | TValue k; | 801 | TValue k; |
784 | setivalue(&k, key); | 802 | setivalue(&k, key); |
785 | cell = luaH_newkey(L, t, &k); | 803 | luaH_newkey(L, t, &k, value); |
786 | } | 804 | } |
787 | setobj2t(L, cell, value); | 805 | else |
806 | setobj2t(L, cast(TValue *, p), value); | ||
788 | } | 807 | } |
789 | 808 | ||
790 | 809 | ||