aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-12-05 14:27:58 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-12-05 14:27:58 -0300
commitbb93f04d87cfc093757dc712905e1fe3fbe65f58 (patch)
tree14f154ea303b10d543266b1e36ad8fb441695a66
parent975d4e0592f980aef09c432302496d834249b6a7 (diff)
downloadlua-bb93f04d87cfc093757dc712905e1fe3fbe65f58.tar.gz
lua-bb93f04d87cfc093757dc712905e1fe3fbe65f58.tar.bz2
lua-bb93f04d87cfc093757dc712905e1fe3fbe65f58.zip
Refactoring of 'luaH_newkey'
Function broke in two and some checks moved to the caller. (We may want to call it without the checks.)
-rw-r--r--lobject.h5
-rw-r--r--ltable.c130
2 files changed, 79 insertions, 56 deletions
diff --git a/lobject.h b/lobject.h
index 4a0835a8..8c06a224 100644
--- a/lobject.h
+++ b/lobject.h
@@ -750,10 +750,9 @@ typedef union Node {
750 750
751 751
752/* copy a value into a key */ 752/* copy a value into a key */
753#define setnodekey(L,node,obj) \ 753#define setnodekey(node,obj) \
754 { Node *n_=(node); const TValue *io_=(obj); \ 754 { Node *n_=(node); const TValue *io_=(obj); \
755 n_->u.key_val = io_->value_; n_->u.key_tt = io_->tt_; \ 755 n_->u.key_val = io_->value_; n_->u.key_tt = io_->tt_; }
756 checkliveness(L,io_); }
757 756
758 757
759/* copy a value from a key */ 758/* copy a value from a key */
diff --git a/ltable.c b/ltable.c
index 6ea382a1..735ae873 100644
--- a/ltable.c
+++ b/ltable.c
@@ -294,14 +294,34 @@ static const TValue *getgeneric (Table *t, const TValue *key, int deadok) {
294 294
295 295
296/* 296/*
297** returns the index for 'k' if 'k' is an appropriate key to live in 297** Return the index 'k' (converted to an unsigned) if it is inside
298** the array part of a table, 0 otherwise. 298** the range [1, limit].
299*/ 299*/
300static unsigned int arrayindex (lua_Integer k) { 300static unsigned checkrange (lua_Integer k, unsigned limit) {
301 if (l_castS2U(k) - 1u < MAXASIZE) /* 'k' in [1, MAXASIZE]? */ 301 return (l_castS2U(k) - 1u < limit) ? cast_uint(k) : 0;
302 return cast_uint(k); /* 'key' is an appropriate array index */ 302}
303 else 303
304 return 0; 304
305/*
306** Return the index 'k' if 'k' is an appropriate key to live in the
307** array part of a table, 0 otherwise.
308*/
309#define arrayindex(k) checkrange(k, MAXASIZE)
310
311
312/*
313** Check whether an integer key is in the array part of a table and
314** return its index there, or zero.
315*/
316#define ikeyinarray(t,k) checkrange(k, t->asize)
317
318
319/*
320** Check whether a key is in the array part of a table and return its
321** index there, or zero.
322*/
323static unsigned keyinarray (Table *t, const TValue *key) {
324 return (ttisinteger(key)) ? ikeyinarray(t, ivalue(key)) : 0;
305} 325}
306 326
307 327
@@ -314,8 +334,8 @@ static unsigned findindex (lua_State *L, Table *t, TValue *key,
314 unsigned asize) { 334 unsigned asize) {
315 unsigned int i; 335 unsigned int i;
316 if (ttisnil(key)) return 0; /* first iteration */ 336 if (ttisnil(key)) return 0; /* first iteration */
317 i = ttisinteger(key) ? arrayindex(ivalue(key)) : 0; 337 i = keyinarray(t, key);
318 if (i - 1u < asize) /* is 'key' inside array part? */ 338 if (i != 0) /* is 'key' inside array part? */
319 return i; /* yes; that's the index */ 339 return i; /* yes; that's the index */
320 else { 340 else {
321 const TValue *n = getgeneric(t, key, 1); 341 const TValue *n = getgeneric(t, key, 1);
@@ -370,14 +390,6 @@ static void freehash (lua_State *L, Table *t) {
370 390
371 391
372/* 392/*
373** Check whether an integer key is in the array part of a table.
374*/
375l_sinline int keyinarray (Table *t, lua_Integer key) {
376 return (l_castS2U(key) - 1u < t->asize); /* 'key' in [1, t->asize]? */
377}
378
379
380/*
381** {============================================================= 393** {=============================================================
382** Rehash 394** Rehash
383** ============================================================== 395** ==============================================================
@@ -829,36 +841,18 @@ static Node *getfreepos (Table *t) {
829** position is free. If not, check whether colliding node is in its main 841** position is free. If not, check whether colliding node is in its main
830** position or not: if it is not, move colliding node to an empty place 842** position or not: if it is not, move colliding node to an empty place
831** and put new key in its main position; otherwise (colliding node is in 843** and put new key in its main position; otherwise (colliding node is in
832** its main position), new key goes to an empty position. 844** its main position), new key goes to an empty position. Return 0 if
845** could not insert key (could not find a free space).
833*/ 846*/
834static void luaH_newkey (lua_State *L, Table *t, const TValue *key, 847static int insertkey (Table *t, const TValue *key, TValue *value) {
835 TValue *value) { 848 Node *mp = mainpositionTV(t, key);
836 Node *mp; 849 /* table cannot already contain the key */
837 TValue aux; 850 lua_assert(isabstkey(getgeneric(t, key, 0)));
838 if (l_unlikely(ttisnil(key)))
839 luaG_runerror(L, "table index is nil");
840 else if (ttisfloat(key)) {
841 lua_Number f = fltvalue(key);
842 lua_Integer k;
843 if (luaV_flttointeger(f, &k, F2Ieq)) { /* does key fit in an integer? */
844 setivalue(&aux, k);
845 key = &aux; /* insert it as an integer */
846 }
847 else if (l_unlikely(luai_numisnan(f)))
848 luaG_runerror(L, "table index is NaN");
849 }
850 if (ttisnil(value))
851 return; /* do not insert nil values */
852 mp = mainpositionTV(t, key);
853 if (!isempty(gval(mp)) || isdummy(t)) { /* main position is taken? */ 851 if (!isempty(gval(mp)) || isdummy(t)) { /* main position is taken? */
854 Node *othern; 852 Node *othern;
855 Node *f = getfreepos(t); /* get a free place */ 853 Node *f = getfreepos(t); /* get a free place */
856 if (f == NULL) { /* cannot find a free place? */ 854 if (f == NULL) /* cannot find a free place? */
857 rehash(L, t, key); /* grow table */ 855 return 0;
858 /* whatever called 'newkey' takes care of TM cache */
859 luaH_set(L, t, key, value); /* insert key into grown table */
860 return;
861 }
862 lua_assert(!isdummy(t)); 856 lua_assert(!isdummy(t));
863 othern = mainpositionfromnode(t, mp); 857 othern = mainpositionfromnode(t, mp);
864 if (othern != mp) { /* is colliding node out of its main position? */ 858 if (othern != mp) { /* is colliding node out of its main position? */
@@ -882,16 +876,31 @@ static void luaH_newkey (lua_State *L, Table *t, const TValue *key,
882 mp = f; 876 mp = f;
883 } 877 }
884 } 878 }
885 setnodekey(L, mp, key); 879 setnodekey(mp, key);
886 luaC_barrierback(L, obj2gco(t), key);
887 lua_assert(isempty(gval(mp))); 880 lua_assert(isempty(gval(mp)));
888 setobj2t(L, gval(mp), value); 881 setobj2t(cast(lua_State *, 0), gval(mp), value);
882 return 1;
883}
884
885
886static void luaH_newkey (lua_State *L, Table *t, const TValue *key,
887 TValue *value) {
888 if (!ttisnil(value)) { /* do not insert nil values */
889 int done = insertkey(t, key, value);
890 if (done)
891 luaC_barrierback(L, obj2gco(t), key);
892 else { /* could not find a free place? */
893 rehash(L, t, key); /* grow table */
894 /* whatever called 'newkey' takes care of TM cache */
895 luaH_set(L, t, key, value); /* insert key into grown table */
896 }
897 }
889} 898}
890 899
891 900
892static const TValue *getintfromhash (Table *t, lua_Integer key) { 901static const TValue *getintfromhash (Table *t, lua_Integer key) {
893 Node *n = hashint(t, key); 902 Node *n = hashint(t, key);
894 lua_assert(!keyinarray(t, key)); 903 lua_assert(!ikeyinarray(t, key));
895 for (;;) { /* check whether 'key' is somewhere in the chain */ 904 for (;;) { /* check whether 'key' is somewhere in the chain */
896 if (keyisinteger(n) && keyival(n) == key) 905 if (keyisinteger(n) && keyival(n) == key)
897 return gval(n); /* that's it */ 906 return gval(n); /* that's it */
@@ -920,10 +929,11 @@ static lu_byte finishnodeget (const TValue *val, TValue *res) {
920 929
921 930
922lu_byte luaH_getint (Table *t, lua_Integer key, TValue *res) { 931lu_byte luaH_getint (Table *t, lua_Integer key, TValue *res) {
923 if (keyinarray(t, key)) { 932 unsigned k = ikeyinarray(t, key);
924 lu_byte tag = *getArrTag(t, key - 1); 933 if (k > 0) {
934 lu_byte tag = *getArrTag(t, k - 1);
925 if (!tagisempty(tag)) 935 if (!tagisempty(tag))
926 farr2val(t, cast_uint(key) - 1, tag, res); 936 farr2val(t, k - 1, tag, res);
927 return tag; 937 return tag;
928 } 938 }
929 else 939 else
@@ -1031,7 +1041,7 @@ static int rawfinishnodeset (const TValue *slot, TValue *val) {
1031 1041
1032 1042
1033int luaH_psetint (Table *t, lua_Integer key, TValue *val) { 1043int luaH_psetint (Table *t, lua_Integer key, TValue *val) {
1034 lua_assert(!keyinarray(t, key)); 1044 lua_assert(!ikeyinarray(t, key));
1035 return finishnodeset(t, getintfromhash(t, key), val); 1045 return finishnodeset(t, getintfromhash(t, key), val);
1036} 1046}
1037 1047
@@ -1081,6 +1091,19 @@ void luaH_finishset (lua_State *L, Table *t, const TValue *key,
1081 TValue *value, int hres) { 1091 TValue *value, int hres) {
1082 lua_assert(hres != HOK); 1092 lua_assert(hres != HOK);
1083 if (hres == HNOTFOUND) { 1093 if (hres == HNOTFOUND) {
1094 TValue aux;
1095 if (l_unlikely(ttisnil(key)))
1096 luaG_runerror(L, "table index is nil");
1097 else if (ttisfloat(key)) {
1098 lua_Number f = fltvalue(key);
1099 lua_Integer k;
1100 if (luaV_flttointeger(f, &k, F2Ieq)) {
1101 setivalue(&aux, k); /* key is equal to an integer */
1102 key = &aux; /* insert it as an integer */
1103 }
1104 else if (l_unlikely(luai_numisnan(f)))
1105 luaG_runerror(L, "table index is NaN");
1106 }
1084 luaH_newkey(L, t, key, value); 1107 luaH_newkey(L, t, key, value);
1085 } 1108 }
1086 else if (hres > 0) { /* regular Node? */ 1109 else if (hres > 0) { /* regular Node? */
@@ -1109,8 +1132,9 @@ void luaH_set (lua_State *L, Table *t, const TValue *key, TValue *value) {
1109** integers cannot be keys to metamethods.) 1132** integers cannot be keys to metamethods.)
1110*/ 1133*/
1111void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) { 1134void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) {
1112 if (keyinarray(t, key)) 1135 unsigned ik = ikeyinarray(t, key);
1113 obj2arr(t, cast_uint(key) - 1, value); 1136 if (ik > 0)
1137 obj2arr(t, ik - 1, value);
1114 else { 1138 else {
1115 int ok = rawfinishnodeset(getintfromhash(t, key), value); 1139 int ok = rawfinishnodeset(getintfromhash(t, key), value);
1116 if (!ok) { 1140 if (!ok) {