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 | ||
