'luaH_get' functions return tag of the result

Undoing previous commit. Returning TValue increases code size without
any visible gains. Returning the tag is a little simpler than returning
a special code (HOK/HNOTFOUND) and the tag is useful by itself in
some cases.
diff --git a/lapi.c b/lapi.c
index a6ef566..2b14c15 100644
--- a/lapi.c
+++ b/lapi.c
@@ -353,7 +353,7 @@
   }
   /* first operand at top - 2, second at top - 1; result go to top - 2 */
   luaO_arith(L, op, s2v(L->top.p - 2), s2v(L->top.p - 1), L->top.p - 2);
-  L->top.p--;  /* remove second operand */
+  L->top.p--;  /* pop second operand */
   lua_unlock(L);
 }
 
@@ -666,47 +666,49 @@
 
 
 static int auxgetstr (lua_State *L, const TValue *t, const char *k) {
-  TValue aux;
+  int tag;
   TString *str = luaS_new(L, k);
-  luaV_fastget(t, str, s2v(L->top.p), luaH_getstr, aux);
-  if (!isemptyV(aux)) {
+  luaV_fastget(t, str, s2v(L->top.p), luaH_getstr, tag);
+  if (!tagisempty(tag)) {
     api_incr_top(L);
   }
   else {
     setsvalue2s(L, L->top.p, str);
     api_incr_top(L);
-    luaV_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, aux);
+    tag = luaV_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, tag);
   }
   lua_unlock(L);
-  return ttype(s2v(L->top.p - 1));
+  return novariant(tag);
 }
 
 
-static TValue getGlobalTable (lua_State *L) {
+static void getGlobalTable (lua_State *L, TValue *gt) {
   Table *registry = hvalue(&G(L)->l_registry);
-  return luaH_getint(registry, LUA_RIDX_GLOBALS);
+  int tag = luaH_getint(registry, LUA_RIDX_GLOBALS, gt);
+  (void)tag;  /* avoid not-used warnings when checks are off */
+  api_check(L, novariant(tag) == LUA_TTABLE, "global table must exist");
 }
 
 
 LUA_API int lua_getglobal (lua_State *L, const char *name) {
   TValue gt;
   lua_lock(L);
-  gt = getGlobalTable(L);
+  getGlobalTable(L, &gt);
   return auxgetstr(L, &gt, name);
 }
 
 
 LUA_API int lua_gettable (lua_State *L, int idx) {
-  TValue aux;
+  int tag;
   TValue *t;
   lua_lock(L);
   api_checkpop(L, 1);
   t = index2value(L, idx);
-  luaV_fastget(t, s2v(L->top.p - 1), s2v(L->top.p - 1), luaH_get, aux);
-  if (isemptyV(aux))
-    luaV_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, aux);
+  luaV_fastget(t, s2v(L->top.p - 1), s2v(L->top.p - 1), luaH_get, tag);
+  if (tagisempty(tag))
+    tag = luaV_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, tag);
   lua_unlock(L);
-  return ttype(s2v(L->top.p - 1));
+  return novariant(tag);
 }
 
 
@@ -718,29 +720,27 @@
 
 LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
   TValue *t;
-  TValue aux;
+  int tag;
   lua_lock(L);
   t = index2value(L, idx);
-  luaV_fastgeti(t, n, s2v(L->top.p), aux);
-  if (isemptyV(aux)) {
+  luaV_fastgeti(t, n, s2v(L->top.p), tag);
+  if (tagisempty(tag)) {
     TValue key;
     setivalue(&key, n);
-    luaV_finishget(L, t, &key, L->top.p, aux);
+    tag = luaV_finishget(L, t, &key, L->top.p, tag);
   }
   api_incr_top(L);
   lua_unlock(L);
-  return ttype(s2v(L->top.p - 1));
+  return novariant(tag);
 }
 
 
-l_sinline int finishrawget (lua_State *L, TValue res) {
-  if (isemptyV(res))  /* avoid copying empty items to the stack */
+static int finishrawget (lua_State *L, int tag) {
+  if (tagisempty(tag))  /* avoid copying empty items to the stack */
     setnilvalue(s2v(L->top.p));
-  else
-    setobjV(L, s2v(L->top.p), res);
   api_incr_top(L);
   lua_unlock(L);
-  return ttypeV(res);
+  return novariant(tag);
 }
 
 
@@ -753,23 +753,23 @@
 
 LUA_API int lua_rawget (lua_State *L, int idx) {
   Table *t;
-  TValue res;
+  int tag;
   lua_lock(L);
   api_checkpop(L, 1);
   t = gettable(L, idx);
-  res = luaH_get(t, s2v(L->top.p - 1));
+  tag = luaH_get(t, s2v(L->top.p - 1), s2v(L->top.p - 1));
   L->top.p--;  /* pop key */
-  return finishrawget(L, res);
+  return finishrawget(L, tag);
 }
 
 
 LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) {
   Table *t;
-  TValue aux;
+  int tag;
   lua_lock(L);
   t = gettable(L, idx);
-  luaH_fastgeti(t, n, s2v(L->top.p), aux);
-  return finishrawget(L, aux);
+  luaH_fastgeti(t, n, s2v(L->top.p), tag);
+  return finishrawget(L, tag);
 }
 
 
@@ -779,7 +779,7 @@
   lua_lock(L);
   t = gettable(L, idx);
   setpvalue(&k, cast_voidp(p));
-  return finishrawget(L, luaH_get(t, &k));
+  return finishrawget(L, luaH_get(t, &k, s2v(L->top.p)));
 }
 
 
@@ -872,7 +872,7 @@
 LUA_API void lua_setglobal (lua_State *L, const char *name) {
   TValue gt;
   lua_lock(L);  /* unlock done in 'auxsetstr' */
-  gt = getGlobalTable(L);
+  getGlobalTable(L, &gt);
   auxsetstr(L, &gt, name);
 }
 
@@ -1122,7 +1122,8 @@
     LClosure *f = clLvalue(s2v(L->top.p - 1));  /* get new function */
     if (f->nupvalues >= 1) {  /* does it have an upvalue? */
       /* get global table from registry */
-      TValue gt = getGlobalTable(L);
+      TValue gt;
+      getGlobalTable(L, &gt);
       /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
       setobj(L, f->upvals[0]->v.p, &gt);
       luaC_barrier(L, f->upvals[0], &gt);
@@ -1266,7 +1267,7 @@
   if (more)
     api_incr_top(L);
   else  /* no more elements */
-    L->top.p -= 1;  /* remove key */
+    L->top.p--;  /* pop key */
   lua_unlock(L);
   return more;
 }
diff --git a/lcode.c b/lcode.c
index 18bf941..2c57fda 100644
--- a/lcode.c
+++ b/lcode.c
@@ -541,11 +541,12 @@
 ** a function can make some indices wrong.
 */
 static int addk (FuncState *fs, TValue *key, TValue *v) {
+  TValue val;
   lua_State *L = fs->ls->L;
   Proto *f = fs->f;
-  TValue val = luaH_get(fs->ls->h, key);  /* query scanner table */
+  int tag = luaH_get(fs->ls->h, key, &val);  /* query scanner table */
   int k, oldsize;
-  if (ttisintegerV(val)) {  /* is there an index there? */
+  if (tag == LUA_VNUMINT) {  /* is there an index there? */
     k = cast_int(ivalue(&val));
     /* correct value? (warning: must distinguish floats from integers!) */
     if (k < fs->nk && ttypetag(&f->k[k]) == ttypetag(v) &&
diff --git a/ldump.c b/ldump.c
index 34b63a8..ca708a4 100644
--- a/ldump.c
+++ b/ldump.c
@@ -132,8 +132,9 @@
   if (ts == NULL)
     dumpSize(D, 0);
   else {
-    TValue idx = luaH_getstr(D->h, ts);
-    if (!isemptyV(idx)) {  /* string already saved? */
+    TValue idx;
+    int tag = luaH_getstr(D->h, ts, &idx);
+    if (!tagisempty(tag)) {  /* string already saved? */
       dumpSize(D, 1);  /* reuse a saved string */
       dumpSize(D, cast_sizet(ivalue(&idx)));  /* index of saved string */
     }
diff --git a/lobject.h b/lobject.h
index 69fa626..b42539c 100644
--- a/lobject.h
+++ b/lobject.h
@@ -75,7 +75,6 @@
 
 /* raw type tag of a TValue */
 #define rawtt(o)	((o)->tt_)
-#define rawttV(o)	((o).tt_)
 
 /* tag with no variants (bits 0-3) */
 #define novariant(t)	((t) & 0x0F)
@@ -83,18 +82,14 @@
 /* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
 #define withvariant(t)	((t) & 0x3F)
 #define ttypetag(o)	withvariant(rawtt(o))
-#define ttypetagV(o)	withvariant(rawttV(o))
 
 /* type of a TValue */
 #define ttype(o)	(novariant(rawtt(o)))
-#define ttypeV(o)	(novariant(rawttV(o)))
 
 
 /* Macros to test type */
 #define checktag(o,t)		(rawtt(o) == (t))
-#define checktagV(o,t)		(rawttV(o) == (t))
 #define checktype(o,t)		(ttype(o) == (t))
-#define checktypeV(o,t)		(ttypeV(o) == (t))
 
 
 /* Macros for internal tests */
@@ -117,7 +112,6 @@
 
 /* set a value's tag */
 #define settt_(o,t)	((o)->tt_=(t))
-#define setttV_(o,t)	((o).tt_=(t))
 
 
 /* main macro to copy values (from 'obj2' to 'obj1') */
@@ -126,11 +120,6 @@
           io1->value_ = io2->value_; settt_(io1, io2->tt_); \
 	  checkliveness(L,io1); lua_assert(!isnonstrictnil(io1)); }
 
-#define setobjV(L,obj1,obj2) \
-	{ TValue *io1=(obj1); const TValue io2=(obj2); \
-          io1->value_ = io2.value_; settt_(io1, io2.tt_); \
-	  checkliveness(L,io1); lua_assert(!isnonstrictnil(io1)); }
-
 /*
 ** Different types of assignments, according to source and destination.
 ** (They are mostly equal now, but may be different in the future.)
@@ -199,16 +188,19 @@
 /* Value returned for a key not found in a table (absent key) */
 #define LUA_VABSTKEY	makevariant(LUA_TNIL, 2)
 
-/* Special "value" to signal that a fast get is accessing a non-table */
-#define LUA_VNOTABLE	makevariant(LUA_TNIL, 3)
-
-#define setnotableV(obj)	setttV_(obj, LUA_VNOTABLE)
+/* Special variant to signal that a fast get is accessing a non-table */
+#define LUA_VNOTABLE    makevariant(LUA_TNIL, 3)
 
 
 /* macro to test for (any kind of) nil */
 #define ttisnil(v)		checktype((v), LUA_TNIL)
-#define ttisnilV(v)		checktypeV((v), LUA_TNIL)
 
+/*
+** Macro to test the result of a table access. Formally, it should
+** distinguish between LUA_VEMPTY/LUA_VABSTKEY/LUA_VNOTABLE and
+** other tags. As currently nil is equivalent to LUA_VEMPTY, it is
+** simpler to just test whether the value is nil.
+*/
 #define tagisempty(tag)		(novariant(tag) == LUA_TNIL)
 
 
@@ -234,7 +226,6 @@
 ** be accepted as empty.)
 */
 #define isempty(v)		ttisnil(v)
-#define isemptyV(v)		checktypeV((v), LUA_TNIL)
 
 
 /* macro defining a value corresponding to an absent key */
@@ -346,7 +337,6 @@
 #define ttisnumber(o)		checktype((o), LUA_TNUMBER)
 #define ttisfloat(o)		checktag((o), LUA_VNUMFLT)
 #define ttisinteger(o)		checktag((o), LUA_VNUMINT)
-#define ttisintegerV(o)		checktagV((o), LUA_VNUMINT)
 
 #define nvalue(o)	check_exp(ttisnumber(o), \
 	(ttisinteger(o) ? cast_num(ivalue(o)) : fltvalue(o)))
diff --git a/ltable.c b/ltable.c
index f675f39..f62f36b 100644
--- a/ltable.c
+++ b/ltable.c
@@ -904,14 +904,23 @@
 }
 
 
-TValue luaH_getint (Table *t, lua_Integer key) {
-  if (keyinarray(t, key)) {
-    TValue res;
-    arr2objV(t, key, res);
-    return res;
+static int finishnodeget (const TValue *val, TValue *res) {
+  if (!ttisnil(val)) {
+    setobj(((lua_State*)NULL), res, val);
   }
-  else 
-    return *getintfromhash(t, key);
+  return ttypetag(val);
+}
+
+
+int luaH_getint (Table *t, lua_Integer key, TValue *res) {
+  if (keyinarray(t, key)) {
+    int tag = *getArrTag(t, key - 1);
+    if (!tagisempty(tag))
+      farr2val(t, key, tag, res);
+    return tag;
+  }
+  else
+    return finishnodeget(getintfromhash(t, key), res);
 }
 
 
@@ -934,8 +943,8 @@
 }
 
 
-TValue luaH_getshortstr (Table *t, TString *key) {
-  return *luaH_Hgetshortstr(t, key);
+int luaH_getshortstr (Table *t, TString *key, TValue *res) {
+  return finishnodeget(luaH_Hgetshortstr(t, key), res);
 }
 
 
@@ -950,8 +959,8 @@
 }
 
 
-TValue luaH_getstr (Table *t, TString *key) {
-  return *Hgetstr(t, key);
+int luaH_getstr (Table *t, TString *key, TValue *res) {
+  return finishnodeget(Hgetstr(t, key), res);
 }
 
 
@@ -967,31 +976,34 @@
 /*
 ** main search function
 */
-TValue luaH_get (Table *t, const TValue *key) {
+int luaH_get (Table *t, const TValue *key, TValue *res) {
+  const TValue *slot;
   switch (ttypetag(key)) {
     case LUA_VSHRSTR:
-      return *luaH_Hgetshortstr(t, tsvalue(key));
+      slot = luaH_Hgetshortstr(t, tsvalue(key));
       break;
     case LUA_VNUMINT:
-      return luaH_getint(t, ivalue(key));
+      return luaH_getint(t, ivalue(key), res);
     case LUA_VNIL:
-      return absentkey;
+      slot = &absentkey;
       break;
     case LUA_VNUMFLT: {
       lua_Integer k;
       if (luaV_flttointeger(fltvalue(key), &k, F2Ieq)) /* integral index? */
-        return luaH_getint(t, k);  /* use specialized version */
+        return luaH_getint(t, k, res);  /* use specialized version */
       /* else... */
     }  /* FALLTHROUGH */
     default:
-      return *getgeneric(t, key, 0);
+      slot = getgeneric(t, key, 0);
+      break;
   }
+  return finishnodeget(slot, res);
 }
 
 
 static int finishnodeset (Table *t, const TValue *slot, TValue *val) {
   if (!ttisnil(slot)) {
-    setobj(cast(lua_State*, NULL), cast(TValue*, slot), val);
+    setobj(((lua_State*)NULL), cast(TValue*, slot), val);
     return HOK;  /* success */
   }
   else if (isabstkey(slot))
@@ -1005,7 +1017,7 @@
   if (isabstkey(slot))
     return 0;  /* no slot with that key */
   else {
-    setobj(cast(lua_State*, NULL), cast(TValue*, slot), val);
+    setobj(((lua_State*)NULL), cast(TValue*, slot), val);
     return 1;  /* success */
   }
 }
diff --git a/ltable.h b/ltable.h
index 10dae5c..1f2ea3e 100644
--- a/ltable.h
+++ b/ltable.h
@@ -46,11 +46,12 @@
 
 
 
-#define luaH_fastgeti(t,k,res,aux) \
+#define luaH_fastgeti(t,k,res,tag) \
   { Table *h = t; lua_Unsigned u = l_castS2U(k); \
-    if ((u - 1u < h->alimit)) arr2objV(h,u,aux); \
-    else aux = luaH_getint(h, u); \
-    if (!isemptyV(aux)) setobjV(cast(lua_State*, NULL), res, aux); }
+    if ((u - 1u < h->alimit)) { \
+      tag = *getArrTag(h,(u)-1u); \
+      if (!tagisempty(tag)) { farr2val(h, u, tag, res); }} \
+    else { tag = luaH_getint(h, u, res); }}
 
 
 #define luaH_fastseti(t,k,val,hres) \
@@ -69,6 +70,8 @@
 #define HFIRSTNODE	3
 
 /*
+** 'luaH_get*' operations set 'res', unless the value is absent, and
+** return the tag of the result,
 ** The 'luaH_pset*' (pre-set) operations set the given value and return
 ** HOK, unless the original value is absent. In that case, if the key
 ** is really absent, they return HNOTFOUND. Otherwise, if there is a
@@ -85,7 +88,8 @@
 /*
 ** The array part of a table is represented by an array of cells.
 ** Each cell is composed of NM tags followed by NM values, so that
-** no space is wasted in padding.
+** no space is wasted in padding. The last cell may be incomplete,
+** that is, it may have fewer than NM values.
 */
 #define NM      cast_uint(sizeof(Value))
 
@@ -105,10 +109,8 @@
 /*
 ** Move TValues to/from arrays, using Lua indices
 */
-#define arr2objV(h,k,val)  \
-  ((val).tt_ = *getArrTag(h,(k)-1u), (val).value_ = *getArrVal(h,(k)-1u))
-
-#define arr2obj(h,k,val)	arr2objV(h,k,*(val))
+#define arr2obj(h,k,val)  \
+  ((val)->tt_ = *getArrTag(h,(k)-1u), (val)->value_ = *getArrVal(h,(k)-1u))
 
 #define obj2arr(h,k,val)  \
   (*getArrTag(h,(k)-1u) = (val)->tt_, *getArrVal(h,(k)-1u) = (val)->value_)
@@ -126,11 +128,12 @@
   (*tag = (val)->tt_, *getArrVal(h,(k)-1u) = (val)->value_)
 
 
-LUAI_FUNC TValue luaH_get (Table *t, const TValue *key);
-LUAI_FUNC TValue luaH_getshortstr (Table *t, TString *key);
-LUAI_FUNC TValue luaH_getstr (Table *t, TString *key);
-LUAI_FUNC TValue luaH_getint (Table *t, lua_Integer key);
+LUAI_FUNC int luaH_get (Table *t, const TValue *key, TValue *res);
+LUAI_FUNC int luaH_getshortstr (Table *t, TString *key, TValue *res);
+LUAI_FUNC int luaH_getstr (Table *t, TString *key, TValue *res);
+LUAI_FUNC int luaH_getint (Table *t, lua_Integer key, TValue *res);
 
+/* Special get for metamethods */
 LUAI_FUNC const TValue *luaH_Hgetshortstr (Table *t, TString *key);
 
 LUAI_FUNC TString *luaH_getstrkey (Table *t, TString *key);
diff --git a/ltests.c b/ltests.c
index 59df7ca..1a34870 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1538,7 +1538,8 @@
     }
     else if EQ("getfield") {
       int t = getindex;
-      lua_getfield(L1, t, getstring);
+      int tp = lua_getfield(L1, t, getstring);
+      lua_assert(tp == lua_type(L1, -1));
     }
     else if EQ("getglobal") {
       lua_getglobal(L1, getstring);
@@ -1548,7 +1549,8 @@
         lua_pushnil(L1);
     }
     else if EQ("gettable") {
-      lua_gettable(L1, getindex);
+      int tp = lua_gettable(L1, getindex);
+      lua_assert(tp == lua_type(L1, -1));
     }
     else if EQ("gettop") {
       lua_pushinteger(L1, lua_gettop(L1));
diff --git a/lundump.c b/lundump.c
index 593a495..51d5dc6 100644
--- a/lundump.c
+++ b/lundump.c
@@ -149,7 +149,8 @@
   }
   else if (size == 1) {  /* previously saved string? */
     lua_Integer idx = cast(lua_Integer, loadSize(S));  /* get its index */
-    TValue stv = luaH_getint(S->h, idx);  /* get its value */
+    TValue stv;
+    luaH_getint(S->h, idx, &stv);  /* get its value */
     *sl = ts = tsvalue(&stv);
     luaC_objbarrier(L, p, ts);
     return;  /* do not save it again */
diff --git a/lvm.c b/lvm.c
index a251f42..cfa9961 100644
--- a/lvm.c
+++ b/lvm.c
@@ -285,13 +285,12 @@
 
 
 /*
-** Finish the table access 'val = t[key]'.
+** Finish the table access 'val = t[key]' and return the tag of the result.
 */
-void luaV_finishget_ (lua_State *L, const TValue *t, TValue *key, StkId val,
-                       int tag) {
+int luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
+                      int tag) {
   int loop;  /* counter to avoid infinite loops */
   const TValue *tm;  /* metamethod */
-  TValue aux;
   for (loop = 0; loop < MAXTAGLOOP; loop++) {
     if (tag == LUA_VNOTABLE) {  /* 't' is not a table? */
       lua_assert(!ttistable(t));
@@ -304,22 +303,22 @@
       tm = fasttm(L, hvalue(t)->metatable, TM_INDEX);  /* table's metamethod */
       if (tm == NULL) {  /* no metamethod? */
         setnilvalue(s2v(val));  /* result is nil */
-        return;
+        return LUA_VNIL;
       }
       /* else will try the metamethod */
     }
     if (ttisfunction(tm)) {  /* is metamethod a function? */
       luaT_callTMres(L, tm, t, key, val);  /* call it */
-      return;
+      return ttypetag(s2v(val));
     }
     t = tm;  /* else try to access 'tm[key]' */
-    luaV_fastget(t, key, s2v(val), luaH_get, aux);
-    if (!isemptyV(aux))
-      return;  /* done */
+    luaV_fastget(t, key, s2v(val), luaH_get, tag);
+    if (!tagisempty(tag))
+      return tag;  /* done */
     /* else repeat (tail call 'luaV_finishget') */
-    tag = ttypetagV(aux);
   }
   luaG_runerror(L, "'__index' chain too long; possible loop");
+  return 0;  /* to avoid warnings */
 }
 
 
@@ -1247,36 +1246,36 @@
         TValue *upval = cl->upvals[GETARG_B(i)]->v.p;
         TValue *rc = KC(i);
         TString *key = tsvalue(rc);  /* key must be a short string */
-        TValue aux;
-        luaV_fastget(upval, key, s2v(ra), luaH_getshortstr, aux);
-        if (isemptyV(aux))
-          Protect(luaV_finishget(L, upval, rc, ra, aux));
+        int tag;
+        luaV_fastget(upval, key, s2v(ra), luaH_getshortstr, tag);
+        if (tagisempty(tag))
+          Protect(luaV_finishget(L, upval, rc, ra, tag));
         vmbreak;
       }
       vmcase(OP_GETTABLE) {
         StkId ra = RA(i);
         TValue *rb = vRB(i);
         TValue *rc = vRC(i);
-        TValue aux;
+        int tag;
         if (ttisinteger(rc)) {  /* fast track for integers? */
-          luaV_fastgeti(rb, ivalue(rc), s2v(ra), aux);
+          luaV_fastgeti(rb, ivalue(rc), s2v(ra), tag);
         }
         else
-          luaV_fastget(rb, rc, s2v(ra), luaH_get, aux);
-        if (isemptyV(aux))  /* fast track for integers? */
-          Protect(luaV_finishget(L, rb, rc, ra, aux));
+          luaV_fastget(rb, rc, s2v(ra), luaH_get, tag);
+        if (tagisempty(tag))
+          Protect(luaV_finishget(L, rb, rc, ra, tag));
         vmbreak;
       }
       vmcase(OP_GETI) {
         StkId ra = RA(i);
         TValue *rb = vRB(i);
         int c = GETARG_C(i);
-        TValue aux;
-        luaV_fastgeti(rb, c, s2v(ra), aux);
-        if (isemptyV(aux)) {
+        int tag;
+        luaV_fastgeti(rb, c, s2v(ra), tag);
+        if (tagisempty(tag)) {
           TValue key;
           setivalue(&key, c);
-          Protect(luaV_finishget(L, rb, &key, ra, aux));
+          Protect(luaV_finishget(L, rb, &key, ra, tag));
         }
         vmbreak;
       }
@@ -1285,10 +1284,10 @@
         TValue *rb = vRB(i);
         TValue *rc = KC(i);
         TString *key = tsvalue(rc);  /* key must be a short string */
-        TValue aux;
-        luaV_fastget(rb, key, s2v(ra), luaH_getshortstr, aux);
-        if (isemptyV(aux))
-          Protect(luaV_finishget(L, rb, rc, ra, aux));
+        int tag;
+        luaV_fastget(rb, key, s2v(ra), luaH_getshortstr, tag);
+        if (tagisempty(tag))
+          Protect(luaV_finishget(L, rb, rc, ra, tag));
         vmbreak;
       }
       vmcase(OP_SETTABUP) {
@@ -1370,14 +1369,14 @@
       }
       vmcase(OP_SELF) {
         StkId ra = RA(i);
-        TValue aux;
+        int tag;
         TValue *rb = vRB(i);
         TValue *rc = RKC(i);
         TString *key = tsvalue(rc);  /* key must be a string */
         setobj2s(L, ra + 1, rb);
-        luaV_fastget(rb, key, s2v(ra), luaH_getstr, aux);
-        if (isemptyV(aux))
-          Protect(luaV_finishget(L, rb, rc, ra, aux));
+        luaV_fastget(rb, key, s2v(ra), luaH_getstr, tag);
+        if (tagisempty(tag))
+          Protect(luaV_finishget(L, rb, rc, ra, tag));
         vmbreak;
       }
       vmcase(OP_ADDI) {
diff --git a/lvm.h b/lvm.h
index 3b11e78..a11db83 100644
--- a/lvm.h
+++ b/lvm.h
@@ -78,19 +78,17 @@
 /*
 ** fast track for 'gettable'
 */
-#define luaV_fastget(t,k,res,f, aux) \
-  {if (!ttistable(t)) setnotableV(aux);  \
-   else { aux = f(hvalue(t), k);  \
-      if (!isemptyV(aux)) { setobjV(cast(lua_State*, NULL), res, aux); } } }
+#define luaV_fastget(t,k,res,f, tag) \
+  (tag = (!ttistable(t) ? LUA_VNOTABLE : f(hvalue(t), k, res)))
 
 
 /*
 ** Special case of 'luaV_fastget' for integers, inlining the fast case
 ** of 'luaH_getint'.
 */
-#define luaV_fastgeti(t,k,res,aux) \
-  { if (!ttistable(t)) setnotableV(aux); \
-  else { luaH_fastgeti(hvalue(t), k, res, aux); } }
+#define luaV_fastgeti(t,k,res,tag) \
+  if (!ttistable(t)) tag = LUA_VNOTABLE; \
+  else { luaH_fastgeti(hvalue(t), k, res, tag); }
 
 
 #define luaV_fastset(t,k,val,hres,f) \
@@ -122,10 +120,8 @@
 LUAI_FUNC int luaV_tointegerns (const TValue *obj, lua_Integer *p,
                                 F2Imod mode);
 LUAI_FUNC int luaV_flttointeger (lua_Number n, lua_Integer *p, F2Imod mode);
-#define luaV_finishget(L,t,key,val,aux)  \
-	luaV_finishget_(L,t,key,val,ttypetagV(aux))
-LUAI_FUNC void luaV_finishget_ (lua_State *L, const TValue *t, TValue *key,
-                                              StkId val, int tag);
+LUAI_FUNC int luaV_finishget (lua_State *L, const TValue *t, TValue *key,
+                                            StkId val, int tag);
 LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
                                              TValue *val, int aux);
 LUAI_FUNC void luaV_finishOp (lua_State *L);