aboutsummaryrefslogtreecommitdiff
path: root/ltable.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2023-05-16 14:55:49 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2023-05-16 14:55:49 -0300
commitf8d30826dda6ee8e99200de57a1997734b853db2 (patch)
treed3a24665802f41fe3216714252ed189006f302cd /ltable.c
parent351ccd733298e08c41937c1baf22a68e62bfeca9 (diff)
downloadlua-f8d30826dda6ee8e99200de57a1997734b853db2.tar.gz
lua-f8d30826dda6ee8e99200de57a1997734b853db2.tar.bz2
lua-f8d30826dda6ee8e99200de57a1997734b853db2.zip
New table API for 'set' functions
Diffstat (limited to 'ltable.c')
-rw-r--r--ltable.c120
1 files changed, 100 insertions, 20 deletions
diff --git a/ltable.c b/ltable.c
index 8fd83fda..902f05a7 100644
--- a/ltable.c
+++ b/ltable.c
@@ -719,15 +719,7 @@ void luaH_newkey (lua_State *L, Table *t, const TValue *key, TValue *value) {
719} 719}
720 720
721 721
722/* 722static const TValue *getintfromarray (Table *t, lua_Integer key) {
723** Search function for integers. If integer is inside 'alimit', get it
724** directly from the array part. Otherwise, if 'alimit' is not equal to
725** the real size of the array, key still can be in the array part. In
726** this case, try to avoid a call to 'luaH_realasize' when key is just
727** one more than the limit (so that it can be incremented without
728** changing the real size of the array).
729*/
730const TValue *luaH_getint (Table *t, lua_Integer key) {
731 if (l_castS2U(key) - 1u < t->alimit) /* 'key' in [1, t->alimit]? */ 723 if (l_castS2U(key) - 1u < t->alimit) /* 'key' in [1, t->alimit]? */
732 return &t->array[key - 1]; 724 return &t->array[key - 1];
733 else if (!limitequalsasize(t) && /* key still may be in the array part? */ 725 else if (!limitequalsasize(t) && /* key still may be in the array part? */
@@ -736,19 +728,40 @@ const TValue *luaH_getint (Table *t, lua_Integer key) {
736 t->alimit = cast_uint(key); /* probably '#t' is here now */ 728 t->alimit = cast_uint(key); /* probably '#t' is here now */
737 return &t->array[key - 1]; 729 return &t->array[key - 1];
738 } 730 }
739 else { 731 else return NULL; /* key is not in the array part */
740 Node *n = hashint(t, key); 732}
741 for (;;) { /* check whether 'key' is somewhere in the chain */ 733
742 if (keyisinteger(n) && keyival(n) == key) 734
743 return gval(n); /* that's it */ 735static const TValue *getintfromhash (Table *t, lua_Integer key) {
744 else { 736 Node *n = hashint(t, key);
745 int nx = gnext(n); 737 lua_assert(l_castS2U(key) - 1u >= luaH_realasize(t));
746 if (nx == 0) break; 738 for (;;) { /* check whether 'key' is somewhere in the chain */
747 n += nx; 739 if (keyisinteger(n) && keyival(n) == key)
748 } 740 return gval(n); /* that's it */
741 else {
742 int nx = gnext(n);
743 if (nx == 0) break;
744 n += nx;
749 } 745 }
750 return &absentkey;
751 } 746 }
747 return &absentkey;
748}
749
750
751/*
752** Search function for integers. If integer is inside 'alimit', get it
753** directly from the array part. Otherwise, if 'alimit' is not equal to
754** the real size of the array, key still can be in the array part. In
755** this case, try to avoid a call to 'luaH_realasize' when key is just
756** one more than the limit (so that it can be incremented without
757** changing the real size of the array).
758*/
759const TValue *luaH_getint (Table *t, lua_Integer key) {
760 const TValue *slot = getintfromarray(t, key);
761 if (slot != NULL)
762 return slot;
763 else
764 return getintfromhash(t, key);
752} 765}
753 766
754 767
@@ -832,6 +845,58 @@ int luaH_get1 (Table *t, const TValue *key, TValue *res) {
832} 845}
833 846
834 847
848static int finishnodeset (Table *t, const TValue *slot, TValue *val) {
849 if (!ttisnil(slot)) {
850 setobj(((lua_State*)NULL), cast(TValue*, slot), val);
851 return HOK; /* success */
852 }
853 else if (isabstkey(slot))
854 return HNOTFOUND; /* no slot with that key */
855 else return (cast(Node*, slot) - t->node) + HFIRSTNODE; /* node encoded */
856}
857
858
859int luaH_setint1 (Table *t, lua_Integer key, TValue *val) {
860 const TValue *slot = getintfromarray(t, key);
861 if (slot != NULL) {
862 if (!ttisnil(slot)) {
863 setobj(((lua_State*)NULL), cast(TValue*, slot), val);
864 return HOK; /* success */
865 }
866 else
867 return ~cast_int(key); /* empty slot in the array part */
868 }
869 else
870 return finishnodeset(t, getintfromhash(t, key), val);
871}
872
873
874int luaH_setshortstr1 (Table *t, TString *key, TValue *val) {
875 return finishnodeset(t, luaH_getshortstr(t, key), val);
876}
877
878
879int luaH_setstr1 (Table *t, TString *key, TValue *val) {
880 return finishnodeset(t, luaH_getstr(t, key), val);
881}
882
883
884int luaH_set1 (Table *t, const TValue *key, TValue *val) {
885 switch (ttypetag(key)) {
886 case LUA_VSHRSTR: return luaH_setshortstr1(t, tsvalue(key), val);
887 case LUA_VNUMINT: return luaH_setint1(t, ivalue(key), val);
888 case LUA_VNIL: return HNOTFOUND;
889 case LUA_VNUMFLT: {
890 lua_Integer k;
891 if (luaV_flttointeger(fltvalue(key), &k, F2Ieq)) /* integral index? */
892 return luaH_setint1(t, k, val); /* use specialized version */
893 /* else... */
894 } /* FALLTHROUGH */
895 default:
896 return finishnodeset(t, getgeneric(t, key, 0), val);
897 }
898}
899
835/* 900/*
836** Finish a raw "set table" operation, where 'slot' is where the value 901** Finish a raw "set table" operation, where 'slot' is where the value
837** should have been (the result of a previous "get table"). 902** should have been (the result of a previous "get table").
@@ -847,6 +912,21 @@ void luaH_finishset (lua_State *L, Table *t, const TValue *key,
847} 912}
848 913
849 914
915void luaH_finishset1 (lua_State *L, Table *t, const TValue *key,
916 TValue *value, int aux) {
917 if (aux == HNOTFOUND) {
918 luaH_newkey(L, t, key, value);
919 }
920 else if (aux > 0) { /* regular Node? */
921 setobj2t(L, gval(gnode(t, aux - HFIRSTNODE)), value);
922 }
923 else { /* array entry */
924 aux = ~aux; /* real index */
925 val2arr(t, aux, getArrTag(t, aux), value);
926 }
927}
928
929
850/* 930/*
851** beware: when using this function you probably need to check a GC 931** beware: when using this function you probably need to check a GC
852** barrier and invalidate the TM cache. 932** barrier and invalidate the TM cache.