diff options
| -rw-r--r-- | lvm.c | 43 |
1 files changed, 22 insertions, 21 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 2.264 2015/11/19 19:16:22 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.265 2015/11/23 11:30:45 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 | */ |
| @@ -153,7 +153,7 @@ static int forlimit (const TValue *obj, lua_Integer *p, lua_Integer step, | |||
| 153 | 153 | ||
| 154 | 154 | ||
| 155 | /* | 155 | /* |
| 156 | ** Complete a table access: if 't' is a table, 'tm' has its metamethod; | 156 | ** Finish a table access: if 't' is a table, 'tm' has its metamethod; |
| 157 | ** otherwise, 'tm' is NULL. | 157 | ** otherwise, 'tm' is NULL. |
| 158 | */ | 158 | */ |
| 159 | void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val, | 159 | void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val, |
| @@ -176,32 +176,33 @@ void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val, | |||
| 176 | } | 176 | } |
| 177 | /* else repeat */ | 177 | /* else repeat */ |
| 178 | } | 178 | } |
| 179 | luaG_runerror(L, "gettable chain too long; possible loop"); | 179 | luaG_runerror(L, "'__index' chain too long; possible loop"); |
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | 182 | ||
| 183 | /* | 183 | /* |
| 184 | ** Main function for table assignment (invoking metamethods if needed). | 184 | ** Finish a table assignment 't[key] = val'. |
| 185 | ** Compute 't[key] = val' | 185 | ** If 'oldval' is NULL, 't' is not a table. Otherwise, 'oldval' points |
| 186 | ** to the entry 't[key]', or to 'luaO_nilobject' if there is no such | ||
| 187 | ** entry. (The value at 'oldval' must be nil, otherwise 'luaV_fastset' | ||
| 188 | ** would have done the job.) | ||
| 186 | */ | 189 | */ |
| 187 | void luaV_finishset (lua_State *L, const TValue *t, TValue *key, | 190 | void luaV_finishset (lua_State *L, const TValue *t, TValue *key, |
| 188 | StkId val, const TValue *oldval) { | 191 | StkId val, const TValue *oldval) { |
| 189 | int loop; /* counter to avoid infinite loops */ | 192 | int loop; /* counter to avoid infinite loops */ |
| 190 | for (loop = 0; loop < MAXTAGLOOP; loop++) { | 193 | for (loop = 0; loop < MAXTAGLOOP; loop++) { |
| 191 | const TValue *tm; | 194 | const TValue *tm; /* '__newindex' metamethod */ |
| 192 | if (oldval != NULL) { | 195 | if (oldval != NULL) { /* is 't' a table? */ |
| 193 | lua_assert(ttistable(t) && ttisnil(oldval)); | 196 | Table *h = hvalue(t); /* save 't' table */ |
| 194 | /* must check the metamethod */ | 197 | lua_assert(ttisnil(oldval)); /* old value must be nil */ |
| 195 | if ((tm = fasttm(L, hvalue(t)->metatable, TM_NEWINDEX)) == NULL && | 198 | tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */ |
| 196 | /* no metamethod; is there a previous entry in the table? */ | 199 | if (tm == NULL) { /* no metamethod? */ |
| 197 | (oldval != luaO_nilobject || | 200 | if (oldval == luaO_nilobject) /* no previous entry? */ |
| 198 | /* no previous entry; must create one. (The next test is | 201 | oldval = luaH_newkey(L, h, key); /* create one */ |
| 199 | always true; we only need the assignment.) */ | ||
| 200 | (oldval = luaH_newkey(L, hvalue(t), key), 1))) { | ||
| 201 | /* no metamethod and (now) there is an entry with given key */ | 202 | /* no metamethod and (now) there is an entry with given key */ |
| 202 | setobj2t(L, cast(TValue *, oldval), val); | 203 | setobj2t(L, cast(TValue *, oldval), val); /* set its new value */ |
| 203 | invalidateTMcache(hvalue(t)); | 204 | invalidateTMcache(h); |
| 204 | luaC_barrierback(L, hvalue(t), val); | 205 | luaC_barrierback(L, h, val); |
| 205 | return; | 206 | return; |
| 206 | } | 207 | } |
| 207 | /* else will try the metamethod */ | 208 | /* else will try the metamethod */ |
| @@ -220,7 +221,7 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key, | |||
| 220 | return; /* done */ | 221 | return; /* done */ |
| 221 | /* else loop */ | 222 | /* else loop */ |
| 222 | } | 223 | } |
| 223 | luaG_runerror(L, "settable chain too long; possible loop"); | 224 | luaG_runerror(L, "'__newindex' chain too long; possible loop"); |
| 224 | } | 225 | } |
| 225 | 226 | ||
| 226 | 227 | ||
| @@ -744,8 +745,8 @@ void luaV_finishOp (lua_State *L) { | |||
| 744 | 745 | ||
| 745 | 746 | ||
| 746 | /* | 747 | /* |
| 747 | ** copy of 'luaV_gettable', but protecting call to potential metamethod | 748 | ** copy of 'luaV_gettable', but protecting the call to potential |
| 748 | ** (which can reallocate the stack) | 749 | ** metamethod (which can reallocate the stack) |
| 749 | */ | 750 | */ |
| 750 | #define gettableProtected(L,t,k,v) { const TValue *aux; \ | 751 | #define gettableProtected(L,t,k,v) { const TValue *aux; \ |
| 751 | if (luaV_fastget(L,t,k,aux,luaH_get)) { setobj2s(L, v, aux); } \ | 752 | if (luaV_fastget(L,t,k,aux,luaH_get)) { setobj2s(L, v, aux); } \ |
