aboutsummaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2015-08-03 16:50:49 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2015-08-03 16:50:49 -0300
commit3b795541c488c7e633567897c9112312007a20a0 (patch)
treebaa671c28bef6a13def34e5872fb81594a168861 /lvm.c
parent20b9e594419787cceaa04c645e485b13a2a9f4dc (diff)
downloadlua-3b795541c488c7e633567897c9112312007a20a0.tar.gz
lua-3b795541c488c7e633567897c9112312007a20a0.tar.bz2
lua-3b795541c488c7e633567897c9112312007a20a0.zip
fast track for 'settable'
Diffstat (limited to 'lvm.c')
-rw-r--r--lvm.c33
1 files changed, 18 insertions, 15 deletions
diff --git a/lvm.c b/lvm.c
index 4cb557f9..706acc43 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.247 2015/07/04 16:31:03 roberto Exp roberto $ 2** $Id: lvm.c,v 2.248 2015/07/20 18:24:50 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -184,40 +184,43 @@ void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
184** Main function for table assignment (invoking metamethods if needed). 184** Main function for table assignment (invoking metamethods if needed).
185** Compute 't[key] = val' 185** Compute 't[key] = val'
186*/ 186*/
187void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { 187void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
188 StkId val, const TValue *oldval) {
188 int loop; /* counter to avoid infinite loops */ 189 int loop; /* counter to avoid infinite loops */
189 for (loop = 0; loop < MAXTAGLOOP; loop++) { 190 for (loop = 0; loop < MAXTAGLOOP; loop++) {
190 const TValue *tm; 191 const TValue *tm;
191 if (ttistable(t)) { /* 't' is a table? */ 192 if (oldval != NULL) {
192 Table *h = hvalue(t); 193 lua_assert(ttistable(t) && ttisnil(oldval));
193 TValue *oldval = cast(TValue *, luaH_get(h, key)); 194 /* must check the metamethod */
194 /* if previous value is not nil, there must be a previous entry 195 if ((tm = fasttm(L, hvalue(t)->metatable, TM_NEWINDEX)) == NULL &&
195 in the table; a metamethod has no relevance */
196 if (!ttisnil(oldval) ||
197 /* previous value is nil; must check the metamethod */
198 ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL &&
199 /* no metamethod; is there a previous entry in the table? */ 196 /* no metamethod; is there a previous entry in the table? */
200 (oldval != luaO_nilobject || 197 (oldval != luaO_nilobject ||
201 /* no previous entry; must create one. (The next test is 198 /* no previous entry; must create one. (The next test is
202 always true; we only need the assignment.) */ 199 always true; we only need the assignment.) */
203 (oldval = luaH_newkey(L, h, key), 1)))) { 200 (oldval = luaH_newkey(L, hvalue(t), key), 1))) {
204 /* no metamethod and (now) there is an entry with given key */ 201 /* no metamethod and (now) there is an entry with given key */
205 setobj2t(L, oldval, val); /* assign new value to that entry */ 202 setobj2t(L, cast(TValue *, oldval), val);
206 invalidateTMcache(h); 203 invalidateTMcache(hvalue(t));
207 luaC_barrierback(L, h, val); 204 luaC_barrierback(L, hvalue(t), val);
208 return; 205 return;
209 } 206 }
210 /* else will try the metamethod */ 207 /* else will try the metamethod */
211 } 208 }
212 else /* not a table; check metamethod */ 209 else { /* not a table; check metamethod */
213 if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) 210 if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
214 luaG_typeerror(L, t, "index"); 211 luaG_typeerror(L, t, "index");
212 }
215 /* try the metamethod */ 213 /* try the metamethod */
216 if (ttisfunction(tm)) { 214 if (ttisfunction(tm)) {
217 luaT_callTM(L, tm, t, key, val, 0); 215 luaT_callTM(L, tm, t, key, val, 0);
218 return; 216 return;
219 } 217 }
220 t = tm; /* else repeat assignment over 'tm' */ 218 t = tm; /* else repeat assignment over 'tm' */
219 if (luaV_fastset(L, t, key, oldval, luaH_get, val)) {
220 setobj2t(L, cast(TValue *, oldval), val);
221 return;
222 }
223 /* else loop */
221 } 224 }
222 luaG_runerror(L, "settable chain too long; possible loop"); 225 luaG_runerror(L, "settable chain too long; possible loop");
223} 226}