| 132 | |
| 133 | |
| 134 | void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { |
| 135 | int loop; |
| 136 | TValue temp; |
| 137 | for (loop = 0; loop < MAXTAGLOOP; loop++) { |
| 138 | const TValue *tm; |
| 139 | if (ttistable(t)) { /* `t' is a table? */ |
| 140 | Table *h = hvalue(t); |
| 141 | TValue *oldval = luaH_set(L, h, key); /* do a primitive set */ |
| 142 | /* oldval is nil=> look for newindex, oldval is not nil => look for usedindex */ |
| 143 | tm = ttisnil(oldval) ? fasttm(L, h->metatable, TM_NEWINDEX) |
| 144 | : fasttm(L, h->metatable, TM_USEDINDEX); /*BZ*/ |
| 145 | if (tm == NULL) { /* no tag method, set the value */ |
| 146 | setobj2t(L, oldval, val); |
| 147 | luaC_barriert(L, h, val); |
| 148 | return; |
| 149 | } |
| 150 | /* else will try the tag method */ |
| 151 | } |
| 152 | else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) { |
| 153 | luaG_typeerror(L, t, "index"); |
| 154 | } |
| 155 | if (ttisfunction(tm)) { |
| 156 | callTM(L, tm, t, key, val); |
| 157 | return; |
| 158 | } |
| 159 | /* else repeat with `tm' */ |
| 160 | setobj(L, &temp, tm); /* avoid pointing inside table (may rehash) */ |
| 161 | t = &temp; |
| 162 | } |
| 163 | luaG_runerror(L, "loop in settable"); |
| 164 | } |
| 165 | |
| 166 | |
| 167 | static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2, |
no test coverage detected