aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-12-04 11:08:42 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-12-04 11:08:42 -0300
commit23051e830a8b212f831443eb888e93e30fa8bb19 (patch)
tree782f56415ad3a8799c4dea8d6d329f1550d3d7c3
parentf15589f3b0da477e5dda8863cbf4c0b36469e36d (diff)
downloadlua-23051e830a8b212f831443eb888e93e30fa8bb19.tar.gz
lua-23051e830a8b212f831443eb888e93e30fa8bb19.tar.bz2
lua-23051e830a8b212f831443eb888e93e30fa8bb19.zip
Changes in the API of 'luaH_set' and related functions
Functions to set values in a table (luaH_set, luaH_newkey, etc.) receive the new value, instead of returning a slot where to put the value.
-rw-r--r--lapi.c4
-rw-r--r--lcode.c8
-rw-r--r--llex.c31
-rw-r--r--ltable.c42
-rw-r--r--ltable.h8
-rw-r--r--lvm.c5
6 files changed, 58 insertions, 40 deletions
diff --git a/lapi.c b/lapi.c
index 9fffcc16..03e756d6 100644
--- a/lapi.c
+++ b/lapi.c
@@ -871,12 +871,10 @@ LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
871 871
872static void aux_rawset (lua_State *L, int idx, TValue *key, int n) { 872static void aux_rawset (lua_State *L, int idx, TValue *key, int n) {
873 Table *t; 873 Table *t;
874 TValue *slot;
875 lua_lock(L); 874 lua_lock(L);
876 api_checknelems(L, n); 875 api_checknelems(L, n);
877 t = gettable(L, idx); 876 t = gettable(L, idx);
878 slot = luaH_set(L, t, key); 877 luaH_set(L, t, key, s2v(L->top - 1));
879 setobj2t(L, slot, s2v(L->top - 1));
880 invalidateTMcache(t); 878 invalidateTMcache(t);
881 luaC_barrierback(L, obj2gco(t), s2v(L->top - 1)); 879 luaC_barrierback(L, obj2gco(t), s2v(L->top - 1));
882 L->top -= n; 880 L->top -= n;
diff --git a/lcode.c b/lcode.c
index 97e427b2..d8d353fe 100644
--- a/lcode.c
+++ b/lcode.c
@@ -545,11 +545,14 @@ static void freeexps (FuncState *fs, expdesc *e1, expdesc *e2) {
545** and try to reuse constants. Because some values should not be used 545** and try to reuse constants. Because some values should not be used
546** as keys (nil cannot be a key, integer keys can collapse with float 546** as keys (nil cannot be a key, integer keys can collapse with float
547** keys), the caller must provide a useful 'key' for indexing the cache. 547** keys), the caller must provide a useful 'key' for indexing the cache.
548** Note that all functions share the same table, so entering or exiting
549** a function can make some indices wrong.
548*/ 550*/
549static int addk (FuncState *fs, TValue *key, TValue *v) { 551static int addk (FuncState *fs, TValue *key, TValue *v) {
552 TValue val;
550 lua_State *L = fs->ls->L; 553 lua_State *L = fs->ls->L;
551 Proto *f = fs->f; 554 Proto *f = fs->f;
552 TValue *idx = luaH_set(L, fs->ls->h, key); /* index scanner table */ 555 const TValue *idx = luaH_get(fs->ls->h, key); /* query scanner table */
553 int k, oldsize; 556 int k, oldsize;
554 if (ttisinteger(idx)) { /* is there an index there? */ 557 if (ttisinteger(idx)) { /* is there an index there? */
555 k = cast_int(ivalue(idx)); 558 k = cast_int(ivalue(idx));
@@ -563,7 +566,8 @@ static int addk (FuncState *fs, TValue *key, TValue *v) {
563 k = fs->nk; 566 k = fs->nk;
564 /* numerical value does not need GC barrier; 567 /* numerical value does not need GC barrier;
565 table has no metatable, so it does not need to invalidate cache */ 568 table has no metatable, so it does not need to invalidate cache */
566 setivalue(idx, k); 569 setivalue(&val, k);
570 luaH_finishset(L, fs->ls->h, key, idx, &val);
567 luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants"); 571 luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
568 while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); 572 while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
569 setobj(L, &f->k[k], v); 573 setobj(L, &f->k[k], v);
diff --git a/llex.c b/llex.c
index 4b8dec99..e9915178 100644
--- a/llex.c
+++ b/llex.c
@@ -122,26 +122,29 @@ l_noret luaX_syntaxerror (LexState *ls, const char *msg) {
122 122
123 123
124/* 124/*
125** creates a new string and anchors it in scanner's table so that 125** Creates a new string and anchors it in scanner's table so that it
126** it will not be collected until the end of the compilation 126** will not be collected until the end of the compilation; by that time
127** (by that time it should be anchored somewhere) 127** it should be anchored somewhere. It also internalizes long strings,
128** ensuring there is only one copy of each unique string. The table
129** here is used as a set: the string enters as the key, while its value
130** is irrelevant. We use the string itself as the value only because it
131** is a TValue readly available. Later, the code generation can change
132** this value.
128*/ 133*/
129TString *luaX_newstring (LexState *ls, const char *str, size_t l) { 134TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
130 lua_State *L = ls->L; 135 lua_State *L = ls->L;
131 TValue *o; /* entry for 'str' */
132 TString *ts = luaS_newlstr(L, str, l); /* create new string */ 136 TString *ts = luaS_newlstr(L, str, l); /* create new string */
133 setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */ 137 const TValue *o = luaH_getstr(ls->h, ts);
134 o = luaH_set(L, ls->h, s2v(L->top - 1)); 138 if (!ttisnil(o)) /* string already present? */
135 if (isempty(o)) { /* not in use yet? */ 139 ts = keystrval(nodefromval(o)); /* get saved copy */
136 /* boolean value does not need GC barrier; 140 else { /* not in use yet */
137 table is not a metatable, so it does not need to invalidate cache */ 141 TValue *stv = s2v(L->top++); /* reserve stack space for string */
138 setbtvalue(o); /* t[string] = true */ 142 setsvalue(L, stv, ts); /* temporarily anchor the string */
143 luaH_finishset(L, ls->h, stv, o, stv); /* t[string] = string */
144 /* table is not a metatable, so it does not need to invalidate cache */
139 luaC_checkGC(L); 145 luaC_checkGC(L);
146 L->top--; /* remove string from stack */
140 } 147 }
141 else { /* string already present */
142 ts = keystrval(nodefromval(o)); /* re-use value previously stored */
143 }
144 L->top--; /* remove string from stack */
145 return ts; 148 return ts;
146} 149}
147 150
diff --git a/ltable.c b/ltable.c
index 7e7cbed9..e9410f99 100644
--- a/ltable.c
+++ b/ltable.c
@@ -485,7 +485,7 @@ static void reinsert (lua_State *L, Table *ot, Table *t) {
485 already present in the table */ 485 already present in the table */
486 TValue k; 486 TValue k;
487 getnodekey(L, &k, old); 487 getnodekey(L, &k, old);
488 setobjt2t(L, luaH_set(L, t, &k), gval(old)); 488 luaH_set(L, t, &k, gval(old));
489 } 489 }
490 } 490 }
491} 491}
@@ -632,7 +632,7 @@ static Node *getfreepos (Table *t) {
632** 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
633** position), new key goes to an empty position. 633** position), new key goes to an empty position.
634*/ 634*/
635TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { 635void luaH_newkey (lua_State *L, Table *t, const TValue *key, TValue *value) {
636 Node *mp; 636 Node *mp;
637 TValue aux; 637 TValue aux;
638 if (unlikely(ttisnil(key))) 638 if (unlikely(ttisnil(key)))
@@ -654,7 +654,8 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
654 if (f == NULL) { /* cannot find a free place? */ 654 if (f == NULL) { /* cannot find a free place? */
655 rehash(L, t, key); /* grow table */ 655 rehash(L, t, key); /* grow table */
656 /* whatever called 'newkey' takes care of TM cache */ 656 /* whatever called 'newkey' takes care of TM cache */
657 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;
658 } 659 }
659 lua_assert(!isdummy(t)); 660 lua_assert(!isdummy(t));
660 othern = mainposition(t, keytt(mp), &keyval(mp)); 661 othern = mainposition(t, keytt(mp), &keyval(mp));
@@ -682,7 +683,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
682 setnodekey(L, mp, key); 683 setnodekey(L, mp, key);
683 luaC_barrierback(L, obj2gco(t), key); 684 luaC_barrierback(L, obj2gco(t), key);
684 lua_assert(isempty(gval(mp))); 685 lua_assert(isempty(gval(mp)));
685 return gval(mp); 686 setobj2t(L, gval(mp), value);
686} 687}
687 688
688 689
@@ -770,28 +771,39 @@ const TValue *luaH_get (Table *t, const TValue *key) {
770 771
771 772
772/* 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*/
779void 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/*
773** 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
774** barrier and invalidate the TM cache. 790** barrier and invalidate the TM cache.
775*/ 791*/
776TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { 792void luaH_set (lua_State *L, Table *t, const TValue *key, TValue *value) {
777 const TValue *p = luaH_get(t, key); 793 const TValue *slot = luaH_get(t, key);
778 if (!isabstkey(p)) 794 luaH_finishset(L, t, key, slot, value);
779 return cast(TValue *, p);
780 else return luaH_newkey(L, t, key);
781} 795}
782 796
783 797
784void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) { 798void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) {
785 const TValue *p = luaH_getint(t, key); 799 const TValue *p = luaH_getint(t, key);
786 TValue *cell; 800 if (isabstkey(p)) {
787 if (!isabstkey(p))
788 cell = cast(TValue *, p);
789 else {
790 TValue k; 801 TValue k;
791 setivalue(&k, key); 802 setivalue(&k, key);
792 cell = luaH_newkey(L, t, &k); 803 luaH_newkey(L, t, &k, value);
793 } 804 }
794 setobj2t(L, cell, value); 805 else
806 setobj2t(L, cast(TValue *, p), value);
795} 807}
796 808
797 809
diff --git a/ltable.h b/ltable.h
index c0060f4b..7bbbcb21 100644
--- a/ltable.h
+++ b/ltable.h
@@ -41,8 +41,12 @@ LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key,
41LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key); 41LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key);
42LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); 42LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
43LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); 43LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
44LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key); 44LUAI_FUNC void luaH_newkey (lua_State *L, Table *t, const TValue *key,
45LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); 45 TValue *value);
46LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key,
47 TValue *value);
48LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key,
49 const TValue *slot, TValue *value);
46LUAI_FUNC Table *luaH_new (lua_State *L); 50LUAI_FUNC Table *luaH_new (lua_State *L);
47LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize, 51LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
48 unsigned int nhsize); 52 unsigned int nhsize);
diff --git a/lvm.c b/lvm.c
index aa3b22bf..ccebdbe0 100644
--- a/lvm.c
+++ b/lvm.c
@@ -337,10 +337,7 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
337 lua_assert(isempty(slot)); /* slot must be empty */ 337 lua_assert(isempty(slot)); /* slot must be empty */
338 tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */ 338 tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */
339 if (tm == NULL) { /* no metamethod? */ 339 if (tm == NULL) { /* no metamethod? */
340 if (isabstkey(slot)) /* no previous entry? */ 340 luaH_finishset(L, h, key, slot, val); /* set new value */
341 slot = luaH_newkey(L, h, key); /* create one */
342 /* no metamethod and (now) there is an entry with given key */
343 setobj2t(L, cast(TValue *, slot), val); /* set its new value */
344 invalidateTMcache(h); 341 invalidateTMcache(h);
345 luaC_barrierback(L, obj2gco(h), val); 342 luaC_barrierback(L, obj2gco(h), val);
346 return; 343 return;