** Finish the table access 'val = t[key]'. ** if 'slot' is NULL, 't' is not a table; otherwise, 'slot' points to ** t[k] entry (which must be empty). */
| 285 | ** t[k] entry (which must be empty). |
| 286 | */ |
| 287 | void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val, |
| 288 | const TValue *slot) { |
| 289 | int loop; /* counter to avoid infinite loops */ |
| 290 | const TValue *tm; /* metamethod */ |
| 291 | for (loop = 0; loop < MAXTAGLOOP; loop++) { |
| 292 | if (slot == NULL) { /* 't' is not a table? */ |
| 293 | lua_assert(!ttistable(t)); |
| 294 | tm = luaT_gettmbyobj(L, t, TM_INDEX); |
| 295 | if (l_unlikely(notm(tm))) |
| 296 | luaG_typeerror(L, t, "index"); /* no metamethod */ |
| 297 | /* else will try the metamethod */ |
| 298 | } |
| 299 | else { /* 't' is a table */ |
| 300 | lua_assert(isempty(slot)); |
| 301 | tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); /* table's metamethod */ |
| 302 | if (tm == NULL) { /* no metamethod? */ |
| 303 | setnilvalue(s2v(val)); /* result is nil */ |
| 304 | return; |
| 305 | } |
| 306 | /* else will try the metamethod */ |
| 307 | } |
| 308 | if (ttisfunction(tm)) { /* is metamethod a function? */ |
| 309 | luaT_callTMres(L, tm, t, key, val); /* call it */ |
| 310 | return; |
| 311 | } |
| 312 | t = tm; /* else try to access 'tm[key]' */ |
| 313 | if (luaV_fastget(L, t, key, slot, luaH_get)) { /* fast track? */ |
| 314 | setobj2s(L, val, slot); /* done */ |
| 315 | return; |
| 316 | } |
| 317 | /* else repeat (tail call 'luaV_finishget') */ |
| 318 | } |
| 319 | luaG_runerror(L, "'__index' chain too long; possible loop"); |
| 320 | } |
| 321 | |
| 322 | |
| 323 | /* |
no test coverage detected