/* Finish the table access 'val = t'. if 'slot' is NULL, 't' is not a table; otherwise, 'slot' points to t entry (which must be nil).  */
void luaV_finishget(lua_State *L, const TValue *t, TValue *key, StkId val, const TValue *slot)
/* Finish the table access 'val = t'. if 'slot' is NULL, 't' is not a table; otherwise, 'slot' points to t entry (which must be nil).  */
void luaV_finishget(lua_State *L, const TValue *t, TValue *key, StkId val, const TValue *slot)
{
  int loop;
  const TValue *tm;
  for (loop = 0; loop < MAXTAGLOOP; loop++) {
    if (slot == NULL) {
      lua_assert(!ttistable(t));
      tm = luaT_gettmbyobj(L, t, TM_INDEX);
      if (ttisnil(tm))
        luaG_typeerror(L, t, "index");
    }
    else {
      lua_assert(ttisnil(slot));
      tm = fasttm(L, hvalue(t)->metatable, TM_INDEX);
      if (tm == NULL) {
        setnilvalue(val);
        return;
      }
    }
    if (ttisfunction(tm)) {
      luaT_callTM(L, tm, t, key, val, 1);
      return;
    }
    t = tm;
    if (luaV_fastget(L,t,key,slot,luaH_get)) {
      setobj2s(L, val, slot);
      return;
    }
  }
  luaG_runerror(L, "'__index' chain too long; possible loop");
}