Jelajahi Sumber

new type 'StackValue' for stack elements
(we may want to put extra info there in the future)

Roberto Ierusalimschy 8 tahun lalu
induk
melakukan
f96497397a
20 mengubah file dengan 409 tambahan dan 351 penghapusan
  1. 142 126
      lapi.c
  2. 2 2
      lcode.c
  3. 15 15
      ldebug.c
  4. 20 18
      ldo.c
  5. 2 2
      ldo.h
  6. 6 6
      lfunc.c
  7. 4 1
      lfunc.h
  8. 5 5
      lgc.c
  9. 2 2
      llex.c
  10. 26 19
      lobject.c
  11. 22 11
      lobject.h
  12. 3 3
      lparser.c
  13. 5 5
      lstate.c
  14. 6 6
      ltable.c
  15. 4 4
      ltests.c
  16. 29 17
      ltm.c
  17. 5 3
      ltm.h
  18. 2 2
      lundump.c
  19. 107 102
      lvm.c
  20. 2 2
      lvm.h

+ 142 - 126
lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 2.268 2017/05/26 19:14:29 roberto Exp roberto $
+** $Id: lapi.c,v 2.269 2017/06/01 20:22:33 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -57,33 +57,48 @@ const char lua_ident[] =
 	api_check(l, isstackindex(i, o), "index not in the stack")
 
 
-static TValue *index2addr (lua_State *L, int idx) {
+static TValue *index2value (lua_State *L, int idx) {
   CallInfo *ci = L->ci;
   if (idx > 0) {
-    TValue *o = ci->func + idx;
+    StkId o = ci->func + idx;
     api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index");
     if (o >= L->top) return NONVALIDVALUE;
-    else return o;
+    else return s2v(o);
   }
   else if (!ispseudo(idx)) {  /* negative index */
     api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
-    return L->top + idx;
+    return s2v(L->top + idx);
   }
   else if (idx == LUA_REGISTRYINDEX)
     return &G(L)->l_registry;
   else {  /* upvalues */
     idx = LUA_REGISTRYINDEX - idx;
     api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
-    if (ttislcf(ci->func))  /* light C function? */
+    if (ttislcf(s2v(ci->func)))  /* light C function? */
       return NONVALIDVALUE;  /* it has no upvalues */
     else {
-      CClosure *func = clCvalue(ci->func);
+      CClosure *func = clCvalue(s2v(ci->func));
       return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : NONVALIDVALUE;
     }
   }
 }
 
 
+static StkId index2stack (lua_State *L, int idx) {
+  CallInfo *ci = L->ci;
+  if (idx > 0) {
+    StkId o = ci->func + idx;
+    api_check(L, o < L->top, "unacceptable index");
+    return o;
+  }
+  else {    /* non-positive index */
+    api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
+    api_check(L, !ispseudo(idx), "invalid index");
+    return L->top + idx;
+  }
+}
+
+
 /*
 ** to be called by 'lua_checkstack' in protected mode, to grow stack
 ** capturing memory errors
@@ -124,7 +139,7 @@ LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
   api_check(from, to->ci->top - to->top >= n, "stack overflow");
   from->top -= n;
   for (i = 0; i < n; i++) {
-    setobj2s(to, to->top, from->top + i);
+    setobjs2s(to, to->top, from->top + i);
     to->top++;  /* stack already checked by previous 'api_check' */
   }
   lua_unlock(to);
@@ -175,7 +190,7 @@ LUA_API void lua_settop (lua_State *L, int idx) {
   if (idx >= 0) {
     api_check(L, idx <= L->stack_last - (func + 1), "new top too large");
     while (L->top < (func + 1) + idx)
-      setnilvalue(L->top++);
+      setnilvalue(s2v(L->top++));
     L->top = (func + 1) + idx;
   }
   else {
@@ -189,11 +204,13 @@ LUA_API void lua_settop (lua_State *L, int idx) {
 /*
 ** Reverse the stack segment from 'from' to 'to'
 ** (auxiliary to 'lua_rotate')
+** Note that we move(copy) only the value inside the stack.
+** (We do not move addicional fields that may exist.)
 */
 static void reverse (lua_State *L, StkId from, StkId to) {
   for (; from < to; from++, to--) {
     TValue temp;
-    setobj(L, &temp, from);
+    setobj(L, &temp, s2v(from));
     setobjs2s(L, from, to);
     setobj2s(L, to, &temp);
   }
@@ -208,8 +225,7 @@ LUA_API void lua_rotate (lua_State *L, int idx, int n) {
   StkId p, t, m;
   lua_lock(L);
   t = L->top - 1;  /* end of stack segment being rotated */
-  p = index2addr(L, idx);  /* start of segment */
-  api_checkstackindex(L, idx, p);
+  p = index2stack(L, idx);  /* start of segment */
   api_check(L, (n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'");
   m = (n >= 0 ? t - n : p - n - 1);  /* end of prefix */
   reverse(L, p, m);  /* reverse the prefix with length 'n' */
@@ -222,12 +238,12 @@ LUA_API void lua_rotate (lua_State *L, int idx, int n) {
 LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
   TValue *fr, *to;
   lua_lock(L);
-  fr = index2addr(L, fromidx);
-  to = index2addr(L, toidx);
+  fr = index2value(L, fromidx);
+  to = index2value(L, toidx);
   api_checkvalidindex(L, to);
   setobj(L, to, fr);
   if (isupvalue(toidx))  /* function upvalue? */
-    luaC_barrier(L, clCvalue(L->ci->func), fr);
+    luaC_barrier(L, clCvalue(s2v(L->ci->func)), fr);
   /* LUA_REGISTRYINDEX does not need gc barrier
      (collector revisits it before finishing collection) */
   lua_unlock(L);
@@ -236,7 +252,7 @@ LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
 
 LUA_API void lua_pushvalue (lua_State *L, int idx) {
   lua_lock(L);
-  setobj2s(L, L->top, index2addr(L, idx));
+  setobj2s(L, L->top, index2value(L, idx));
   api_incr_top(L);
   lua_unlock(L);
 }
@@ -249,7 +265,7 @@ LUA_API void lua_pushvalue (lua_State *L, int idx) {
 
 
 LUA_API int lua_type (lua_State *L, int idx) {
-  StkId o = index2addr(L, idx);
+  const TValue *o = index2value(L, idx);
   return (isvalid(o) ? ttnov(o) : LUA_TNONE);
 }
 
@@ -262,39 +278,39 @@ LUA_API const char *lua_typename (lua_State *L, int t) {
 
 
 LUA_API int lua_iscfunction (lua_State *L, int idx) {
-  StkId o = index2addr(L, idx);
+  const TValue *o = index2value(L, idx);
   return (ttislcf(o) || (ttisCclosure(o)));
 }
 
 
 LUA_API int lua_isinteger (lua_State *L, int idx) {
-  StkId o = index2addr(L, idx);
+  const TValue *o = index2value(L, idx);
   return ttisinteger(o);
 }
 
 
 LUA_API int lua_isnumber (lua_State *L, int idx) {
   lua_Number n;
-  const TValue *o = index2addr(L, idx);
+  const TValue *o = index2value(L, idx);
   return tonumber(o, &n);
 }
 
 
 LUA_API int lua_isstring (lua_State *L, int idx) {
-  const TValue *o = index2addr(L, idx);
+  const TValue *o = index2value(L, idx);
   return (ttisstring(o) || cvt2str(o));
 }
 
 
 LUA_API int lua_isuserdata (lua_State *L, int idx) {
-  const TValue *o = index2addr(L, idx);
+  const TValue *o = index2value(L, idx);
   return (ttisfulluserdata(o) || ttislightuserdata(o));
 }
 
 
 LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
-  StkId o1 = index2addr(L, index1);
-  StkId o2 = index2addr(L, index2);
+  const TValue *o1 = index2value(L, index1);
+  const TValue *o2 = index2value(L, index2);
   return (isvalid(o1) && isvalid(o2)) ? luaV_rawequalobj(o1, o2) : 0;
 }
 
@@ -309,18 +325,19 @@ LUA_API void lua_arith (lua_State *L, int op) {
     api_incr_top(L);
   }
   /* first operand at top - 2, second at top - 1; result go to top - 2 */
-  luaO_arith(L, op, L->top - 2, L->top - 1, L->top - 2);
+  luaO_arith(L, op, s2v(L->top - 2), s2v(L->top - 1), L->top - 2);
   L->top--;  /* remove second operand */
   lua_unlock(L);
 }
 
 
 LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
-  StkId o1, o2;
+  const TValue *o1;
+  const TValue *o2;
   int i = 0;
   lua_lock(L);  /* may call tag method */
-  o1 = index2addr(L, index1);
-  o2 = index2addr(L, index2);
+  o1 = index2value(L, index1);
+  o2 = index2value(L, index2);
   if (isvalid(o1) && isvalid(o2)) {
     switch (op) {
       case LUA_OPEQ: i = luaV_equalobj(L, o1, o2); break;
@@ -335,7 +352,7 @@ LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
 
 
 LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) {
-  size_t sz = luaO_str2num(s, L->top);
+  size_t sz = luaO_str2num(s, s2v(L->top));
   if (sz != 0)
     api_incr_top(L);
   return sz;
@@ -344,7 +361,7 @@ LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) {
 
 LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *pisnum) {
   lua_Number n;
-  const TValue *o = index2addr(L, idx);
+  const TValue *o = index2value(L, idx);
   int isnum = tonumber(o, &n);
   if (!isnum)
     n = 0;  /* call to 'tonumber' may change 'n' even if it fails */
@@ -355,7 +372,7 @@ LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *pisnum) {
 
 LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *pisnum) {
   lua_Integer res;
-  const TValue *o = index2addr(L, idx);
+  const TValue *o = index2value(L, idx);
   int isnum = tointeger(o, &res);
   if (!isnum)
     res = 0;  /* call to 'tointeger' may change 'n' even if it fails */
@@ -365,13 +382,13 @@ LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *pisnum) {
 
 
 LUA_API int lua_toboolean (lua_State *L, int idx) {
-  const TValue *o = index2addr(L, idx);
+  const TValue *o = index2value(L, idx);
   return !l_isfalse(o);
 }
 
 
 LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
-  StkId o = index2addr(L, idx);
+  TValue *o = index2value(L, idx);
   if (!ttisstring(o)) {
     if (!cvt2str(o)) {  /* not convertible? */
       if (len != NULL) *len = 0;
@@ -380,7 +397,7 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
     lua_lock(L);  /* 'luaO_tostring' may create a new string */
     luaO_tostring(L, o);
     luaC_checkGC(L);
-    o = index2addr(L, idx);  /* previous call may reallocate the stack */
+    o = index2value(L, idx);  /* previous call may reallocate the stack */
     lua_unlock(L);
   }
   if (len != NULL)
@@ -390,7 +407,7 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
 
 
 LUA_API lua_Unsigned lua_rawlen (lua_State *L, int idx) {
-  StkId o = index2addr(L, idx);
+  const TValue *o = index2value(L, idx);
   switch (ttype(o)) {
     case LUA_TSHRSTR: return tsvalue(o)->shrlen;
     case LUA_TLNGSTR: return tsvalue(o)->u.lnglen;
@@ -402,7 +419,7 @@ LUA_API lua_Unsigned lua_rawlen (lua_State *L, int idx) {
 
 
 LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
-  StkId o = index2addr(L, idx);
+  const TValue *o = index2value(L, idx);
   if (ttislcf(o)) return fvalue(o);
   else if (ttisCclosure(o))
     return clCvalue(o)->f;
@@ -411,7 +428,7 @@ LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
 
 
 LUA_API void *lua_touserdata (lua_State *L, int idx) {
-  StkId o = index2addr(L, idx);
+  const TValue *o = index2value(L, idx);
   switch (ttnov(o)) {
     case LUA_TUSERDATA: return getudatamem(uvalue(o));
     case LUA_TLIGHTUSERDATA: return pvalue(o);
@@ -421,13 +438,13 @@ LUA_API void *lua_touserdata (lua_State *L, int idx) {
 
 
 LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
-  StkId o = index2addr(L, idx);
+  const TValue *o = index2value(L, idx);
   return (!ttisthread(o)) ? NULL : thvalue(o);
 }
 
 
 LUA_API const void *lua_topointer (lua_State *L, int idx) {
-  StkId o = index2addr(L, idx);
+  const TValue *o = index2value(L, idx);
   switch (ttype(o)) {
     case LUA_TTABLE: return hvalue(o);
     case LUA_TLCL: return clLvalue(o);
@@ -449,7 +466,7 @@ LUA_API const void *lua_topointer (lua_State *L, int idx) {
 
 LUA_API void lua_pushnil (lua_State *L) {
   lua_lock(L);
-  setnilvalue(L->top);
+  setnilvalue(s2v(L->top));
   api_incr_top(L);
   lua_unlock(L);
 }
@@ -457,7 +474,7 @@ LUA_API void lua_pushnil (lua_State *L) {
 
 LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
   lua_lock(L);
-  setfltvalue(L->top, n);
+  setfltvalue(s2v(L->top), n);
   api_incr_top(L);
   lua_unlock(L);
 }
@@ -465,7 +482,7 @@ LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
 
 LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
   lua_lock(L);
-  setivalue(L->top, n);
+  setivalue(s2v(L->top), n);
   api_incr_top(L);
   lua_unlock(L);
 }
@@ -491,7 +508,7 @@ LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
 LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
   lua_lock(L);
   if (s == NULL)
-    setnilvalue(L->top);
+    setnilvalue(s2v(L->top));
   else {
     TString *ts;
     ts = luaS_new(L, s);
@@ -532,7 +549,7 @@ LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
 LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
   lua_lock(L);
   if (n == 0) {
-    setfvalue(L->top, fn);
+    setfvalue(s2v(L->top), fn);
   }
   else {
     CClosure *cl;
@@ -542,10 +559,10 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
     cl->f = fn;
     L->top -= n;
     while (n--) {
-      setobj2n(L, &cl->upvalue[n], L->top + n);
+      setobj2n(L, &cl->upvalue[n], s2v(L->top + n));
       /* does not need barrier because closure is white */
     }
-    setclCvalue(L, L->top, cl);
+    setclCvalue(L, s2v(L->top), cl);
   }
   api_incr_top(L);
   luaC_checkGC(L);
@@ -555,7 +572,7 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
 
 LUA_API void lua_pushboolean (lua_State *L, int b) {
   lua_lock(L);
-  setbvalue(L->top, (b != 0));  /* ensure that true is 1 */
+  setbvalue(s2v(L->top), (b != 0));  /* ensure that true is 1 */
   api_incr_top(L);
   lua_unlock(L);
 }
@@ -563,7 +580,7 @@ LUA_API void lua_pushboolean (lua_State *L, int b) {
 
 LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
   lua_lock(L);
-  setpvalue(L->top, p);
+  setpvalue(s2v(L->top), p);
   api_incr_top(L);
   lua_unlock(L);
 }
@@ -571,7 +588,7 @@ LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
 
 LUA_API int lua_pushthread (lua_State *L) {
   lua_lock(L);
-  setthvalue(L, L->top, L);
+  setthvalue(L, s2v(L->top), L);
   api_incr_top(L);
   lua_unlock(L);
   return (G(L)->mainthread == L);
@@ -594,10 +611,10 @@ static int auxgetstr (lua_State *L, const TValue *t, const char *k) {
   else {
     setsvalue2s(L, L->top, str);
     api_incr_top(L);
-    luaV_finishget(L, t, L->top - 1, L->top - 1, slot);
+    luaV_finishget(L, t, s2v(L->top - 1), L->top - 1, slot);
   }
   lua_unlock(L);
-  return ttnov(L->top - 1);
+  return ttnov(s2v(L->top - 1));
 }
 
 
@@ -610,30 +627,30 @@ LUA_API int lua_getglobal (lua_State *L, const char *name) {
 
 LUA_API int lua_gettable (lua_State *L, int idx) {
   const TValue *slot;
-  StkId t;
+  TValue *t;
   lua_lock(L);
-  t = index2addr(L, idx);
-  if (luaV_fastget(L, t, L->top - 1, slot, luaH_get)) {
+  t = index2value(L, idx);
+  if (luaV_fastget(L, t, s2v(L->top - 1), slot, luaH_get)) {
     setobj2s(L, L->top - 1, slot);
   }
   else
-    luaV_finishget(L, t, L->top - 1, L->top - 1, slot);
+    luaV_finishget(L, t, s2v(L->top - 1), L->top - 1, slot);
   lua_unlock(L);
-  return ttnov(L->top - 1);
+  return ttnov(s2v(L->top - 1));
 }
 
 
 LUA_API int lua_getfield (lua_State *L, int idx, const char *k) {
   lua_lock(L);
-  return auxgetstr(L, index2addr(L, idx), k);
+  return auxgetstr(L, index2value(L, idx), k);
 }
 
 
 LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
-  StkId t;
+  TValue *t;
   const TValue *slot;
   lua_lock(L);
-  t = index2addr(L, idx);
+  t = index2value(L, idx);
   if (luaV_fastgeti(L, t, n, slot)) {
     setobj2s(L, L->top, slot);
   }
@@ -644,44 +661,44 @@ LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
   }
   api_incr_top(L);
   lua_unlock(L);
-  return ttnov(L->top - 1);
+  return ttnov(s2v(L->top - 1));
 }
 
 
 LUA_API int lua_rawget (lua_State *L, int idx) {
-  StkId t;
+  TValue *t;
   lua_lock(L);
-  t = index2addr(L, idx);
+  t = index2value(L, idx);
   api_check(L, ttistable(t), "table expected");
-  setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
+  setobj2s(L, L->top - 1, luaH_get(hvalue(t), s2v(L->top - 1)));
   lua_unlock(L);
-  return ttnov(L->top - 1);
+  return ttnov(s2v(L->top - 1));
 }
 
 
 LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) {
-  StkId t;
+  TValue *t;
   lua_lock(L);
-  t = index2addr(L, idx);
+  t = index2value(L, idx);
   api_check(L, ttistable(t), "table expected");
   setobj2s(L, L->top, luaH_getint(hvalue(t), n));
   api_incr_top(L);
   lua_unlock(L);
-  return ttnov(L->top - 1);
+  return ttnov(s2v(L->top - 1));
 }
 
 
 LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
-  StkId t;
+  TValue *t;
   TValue k;
   lua_lock(L);
-  t = index2addr(L, idx);
+  t = index2value(L, idx);
   api_check(L, ttistable(t), "table expected");
   setpvalue(&k, cast(void *, p));
   setobj2s(L, L->top, luaH_get(hvalue(t), &k));
   api_incr_top(L);
   lua_unlock(L);
-  return ttnov(L->top - 1);
+  return ttnov(s2v(L->top - 1));
 }
 
 
@@ -689,7 +706,7 @@ LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
   Table *t;
   lua_lock(L);
   t = luaH_new(L);
-  sethvalue(L, L->top, t);
+  sethvalue2s(L, L->top, t);
   api_incr_top(L);
   if (narray > 0 || nrec > 0)
     luaH_resize(L, t, narray, nrec);
@@ -703,7 +720,7 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
   Table *mt;
   int res = 0;
   lua_lock(L);
-  obj = index2addr(L, objindex);
+  obj = index2value(L, objindex);
   switch (ttnov(obj)) {
     case LUA_TTABLE:
       mt = hvalue(obj)->metatable;
@@ -716,7 +733,7 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
       break;
   }
   if (mt != NULL) {
-    sethvalue(L, L->top, mt);
+    sethvalue2s(L, L->top, mt);
     api_incr_top(L);
     res = 1;
   }
@@ -726,14 +743,14 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
 
 
 LUA_API int lua_getuservalue (lua_State *L, int idx) {
-  StkId o;
+  TValue *o;
   lua_lock(L);
-  o = index2addr(L, idx);
+  o = index2value(L, idx);
   api_check(L, ttisfulluserdata(o), "full userdata expected");
-  getuservalue(L, uvalue(o), L->top);
+  getuservalue(L, uvalue(o), s2v(L->top));
   api_incr_top(L);
   lua_unlock(L);
-  return ttnov(L->top - 1);
+  return ttnov(s2v(L->top - 1));
 }
 
 
@@ -749,13 +766,13 @@ static void auxsetstr (lua_State *L, const TValue *t, const char *k) {
   TString *str = luaS_new(L, k);
   api_checknelems(L, 1);
   if (luaV_fastget(L, t, str, slot, luaH_getstr)) {
-    luaV_finishfastset(L, t, slot, L->top - 1);
+    luaV_finishfastset(L, t, slot, s2v(L->top - 1));
     L->top--;  /* pop value */
   }
   else {
     setsvalue2s(L, L->top, str);  /* push 'str' (to make it a TValue) */
     api_incr_top(L);
-    luaV_finishset(L, t, L->top - 1, L->top - 2, slot);
+    luaV_finishset(L, t, s2v(L->top - 1), s2v(L->top - 2), slot);
     L->top -= 2;  /* pop value and key */
   }
   lua_unlock(L);  /* lock done by caller */
@@ -770,16 +787,16 @@ LUA_API void lua_setglobal (lua_State *L, const char *name) {
 
 
 LUA_API void lua_settable (lua_State *L, int idx) {
-  StkId t;
+  TValue *t;
   const TValue *slot;
   lua_lock(L);
   api_checknelems(L, 2);
-  t = index2addr(L, idx);
-  if (luaV_fastget(L, t, L->top - 2, slot, luaH_get)) {
-    luaV_finishfastset(L, t, slot, L->top - 1);
+  t = index2value(L, idx);
+  if (luaV_fastget(L, t, s2v(L->top - 2), slot, luaH_get)) {
+    luaV_finishfastset(L, t, slot, s2v(L->top - 1));
   }
   else
-    luaV_finishset(L, t, L->top - 2, L->top - 1, slot);
+    luaV_finishset(L, t, s2v(L->top - 2), s2v(L->top - 1), slot);
   L->top -= 2;  /* pop index and value */
   lua_unlock(L);
 }
@@ -787,23 +804,23 @@ LUA_API void lua_settable (lua_State *L, int idx) {
 
 LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
   lua_lock(L);  /* unlock done in 'auxsetstr' */
-  auxsetstr(L, index2addr(L, idx), k);
+  auxsetstr(L, index2value(L, idx), k);
 }
 
 
 LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
-  StkId t;
+  TValue *t;
   const TValue *slot;
   lua_lock(L);
   api_checknelems(L, 1);
-  t = index2addr(L, idx);
+  t = index2value(L, idx);
   if (luaV_fastgeti(L, t, n, slot)) {
-    luaV_finishfastset(L, t, slot, L->top - 1);
+    luaV_finishfastset(L, t, slot, s2v(L->top - 1));
   }
   else {
     TValue aux;
     setivalue(&aux, n);
-    luaV_finishset(L, t, &aux, L->top - 1, slot);
+    luaV_finishset(L, t, &aux, s2v(L->top - 1), slot);
   }
   L->top--;  /* pop value */
   lua_unlock(L);
@@ -811,45 +828,45 @@ LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
 
 
 LUA_API void lua_rawset (lua_State *L, int idx) {
-  StkId o;
+  TValue *o;
   TValue *slot;
   lua_lock(L);
   api_checknelems(L, 2);
-  o = index2addr(L, idx);
+  o = index2value(L, idx);
   api_check(L, ttistable(o), "table expected");
-  slot = luaH_set(L, hvalue(o), L->top - 2);
-  setobj2t(L, slot, L->top - 1);
+  slot = luaH_set(L, hvalue(o), s2v(L->top - 2));
+  setobj2t(L, slot, s2v(L->top - 1));
   invalidateTMcache(hvalue(o));
-  luaC_barrierback(L, hvalue(o), L->top-1);
+  luaC_barrierback(L, hvalue(o), s2v(L->top - 1));
   L->top -= 2;
   lua_unlock(L);
 }
 
 
 LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) {
-  StkId o;
+  TValue *o;
   lua_lock(L);
   api_checknelems(L, 1);
-  o = index2addr(L, idx);
+  o = index2value(L, idx);
   api_check(L, ttistable(o), "table expected");
-  luaH_setint(L, hvalue(o), n, L->top - 1);
-  luaC_barrierback(L, hvalue(o), L->top-1);
+  luaH_setint(L, hvalue(o), n, s2v(L->top - 1));
+  luaC_barrierback(L, hvalue(o), s2v(L->top - 1));
   L->top--;
   lua_unlock(L);
 }
 
 
 LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) {
-  StkId o;
+  TValue *o;
   TValue k, *slot;
   lua_lock(L);
   api_checknelems(L, 1);
-  o = index2addr(L, idx);
+  o = index2value(L, idx);
   api_check(L, ttistable(o), "table expected");
   setpvalue(&k, cast(void *, p));
   slot = luaH_set(L, hvalue(o), &k);
-  setobj2t(L, slot, L->top - 1);
-  luaC_barrierback(L, hvalue(o), L->top - 1);
+  setobj2t(L, slot, s2v(L->top - 1));
+  luaC_barrierback(L, hvalue(o), s2v(L->top - 1));
   L->top--;
   lua_unlock(L);
 }
@@ -860,12 +877,12 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
   Table *mt;
   lua_lock(L);
   api_checknelems(L, 1);
-  obj = index2addr(L, objindex);
-  if (ttisnil(L->top - 1))
+  obj = index2value(L, objindex);
+  if (ttisnil(s2v(L->top - 1)))
     mt = NULL;
   else {
-    api_check(L, ttistable(L->top - 1), "table expected");
-    mt = hvalue(L->top - 1);
+    api_check(L, ttistable(s2v(L->top - 1)), "table expected");
+    mt = hvalue(s2v(L->top - 1));
   }
   switch (ttnov(obj)) {
     case LUA_TTABLE: {
@@ -896,13 +913,13 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
 
 
 LUA_API void lua_setuservalue (lua_State *L, int idx) {
-  StkId o;
+  TValue *o;
   lua_lock(L);
   api_checknelems(L, 1);
-  o = index2addr(L, idx);
+  o = index2value(L, idx);
   api_check(L, ttisfulluserdata(o), "full userdata expected");
-  setuservalue(L, uvalue(o), L->top - 1);
-  luaC_barrier(L, gcvalue(o), L->top - 1);
+  setuservalue(L, uvalue(o), s2v(L->top - 1));
+  luaC_barrier(L, gcvalue(o), s2v(L->top - 1));
   L->top--;
   lua_unlock(L);
 }
@@ -971,8 +988,7 @@ LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
   if (errfunc == 0)
     func = 0;
   else {
-    StkId o = index2addr(L, errfunc);
-    api_checkstackindex(L, errfunc, o);
+    StkId o = index2stack(L, errfunc);
     func = savestack(L, o);
   }
   c.func = L->top - (nargs+1);  /* function to be called */
@@ -1010,7 +1026,7 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
   luaZ_init(L, &z, reader, data);
   status = luaD_protectedparser(L, &z, chunkname, mode);
   if (status == LUA_OK) {  /* no errors? */
-    LClosure *f = clLvalue(L->top - 1);  /* get newly created function */
+    LClosure *f = clLvalue(s2v(L->top - 1));  /* get newly created function */
     if (f->nupvalues >= 1) {  /* does it have an upvalue? */
       /* get global table from registry */
       Table *reg = hvalue(&G(L)->l_registry);
@@ -1030,7 +1046,7 @@ LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) {
   TValue *o;
   lua_lock(L);
   api_checknelems(L, 1);
-  o = L->top - 1;
+  o = s2v(L->top - 1);
   if (isLfunction(o))
     status = luaU_dump(L, getproto(o), writer, data, strip);
   else
@@ -1154,10 +1170,10 @@ LUA_API int lua_error (lua_State *L) {
 
 
 LUA_API int lua_next (lua_State *L, int idx) {
-  StkId t;
+  TValue *t;
   int more;
   lua_lock(L);
-  t = index2addr(L, idx);
+  t = index2value(L, idx);
   api_check(L, ttistable(t), "table expected");
   more = luaH_next(L, hvalue(t), L->top - 1);
   if (more) {
@@ -1187,9 +1203,9 @@ LUA_API void lua_concat (lua_State *L, int n) {
 
 
 LUA_API void lua_len (lua_State *L, int idx) {
-  StkId t;
+  TValue *t;
   lua_lock(L);
-  t = index2addr(L, idx);
+  t = index2value(L, idx);
   luaV_objlen(L, L->top, t);
   api_incr_top(L);
   lua_unlock(L);
@@ -1218,7 +1234,7 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
   Udata *u;
   lua_lock(L);
   u = luaS_newudata(L, size);
-  setuvalue(L, L->top, u);
+  setuvalue(L, s2v(L->top), u);
   api_incr_top(L);
   luaC_checkGC(L);
   lua_unlock(L);
@@ -1227,7 +1243,7 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
 
 
 
-static const char *aux_upvalue (StkId fi, int n, TValue **val,
+static const char *aux_upvalue (TValue *fi, int n, TValue **val,
                                 GCObject **owner) {
   switch (ttype(fi)) {
     case LUA_TCCL: {  /* C closure */
@@ -1256,7 +1272,7 @@ LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
   const char *name;
   TValue *val = NULL;  /* to avoid warnings */
   lua_lock(L);
-  name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL);
+  name = aux_upvalue(index2value(L, funcindex), n, &val, NULL);
   if (name) {
     setobj2s(L, L->top, val);
     api_incr_top(L);
@@ -1270,14 +1286,14 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
   const char *name;
   TValue *val = NULL;  /* to avoid warnings */
   GCObject *owner = NULL;  /* to avoid warnings */
-  StkId fi;
+  TValue *fi;
   lua_lock(L);
-  fi = index2addr(L, funcindex);
+  fi = index2value(L, funcindex);
   api_checknelems(L, 1);
   name = aux_upvalue(fi, n, &val, &owner);
   if (name) {
     L->top--;
-    setobj(L, val, L->top);
+    setobj(L, val, s2v(L->top));
     luaC_barrier(L, owner, val);
   }
   lua_unlock(L);
@@ -1287,7 +1303,7 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
 
 static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
   LClosure *f;
-  StkId fi = index2addr(L, fidx);
+  TValue *fi = index2value(L, fidx);
   api_check(L, ttisLclosure(fi), "Lua function expected");
   f = clLvalue(fi);
   api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
@@ -1297,7 +1313,7 @@ static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
 
 
 LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
-  StkId fi = index2addr(L, fidx);
+  TValue *fi = index2value(L, fidx);
   switch (ttype(fi)) {
     case LUA_TLCL: {  /* lua closure */
       return *getupvalref(L, fidx, n, NULL);

+ 2 - 2
lcode.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lcode.c,v 2.119 2017/05/18 19:44:19 roberto Exp roberto $
+** $Id: lcode.c,v 2.120 2017/06/27 11:35:31 roberto Exp roberto $
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -1079,7 +1079,7 @@ static int constfolding (FuncState *fs, int op, expdesc *e1,
   TValue v1, v2, res;
   if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2))
     return 0;  /* non-numeric operands or not safe to fold */
-  luaO_arith(fs->ls->L, op, &v1, &v2, &res);  /* does operation */
+  luaO_rawarith(fs->ls->L, op, &v1, &v2, &res);  /* does operation */
   if (ttisinteger(&res)) {
     e1->k = VKINT;
     e1->u.ival = ivalue(&res);

+ 15 - 15
ldebug.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.c,v 2.126 2017/05/13 13:54:47 roberto Exp roberto $
+** $Id: ldebug.c,v 2.127 2017/06/27 11:35:31 roberto Exp roberto $
 ** Debug Interface
 ** See Copyright Notice in lua.h
 */
@@ -35,7 +35,7 @@
 
 
 /* Active Lua function (given call info) */
-#define ci_func(ci)		(clLvalue((ci)->func))
+#define ci_func(ci)		(clLvalue(s2v((ci)->func)))
 
 
 static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
@@ -211,16 +211,16 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
   lua_lock(L);
   swapextra(L);
   if (ar == NULL) {  /* information about non-active function? */
-    if (!isLfunction(L->top - 1))  /* not a Lua function? */
+    if (!isLfunction(s2v(L->top - 1)))  /* not a Lua function? */
       name = NULL;
     else  /* consider live variables at function start (parameters) */
-      name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0);
+      name = luaF_getlocalname(clLvalue(s2v(L->top - 1))->p, n, 0);
   }
   else {  /* active function; get information through 'ar' */
     StkId pos = NULL;  /* to avoid warnings */
     name = findlocal(L, ar->i_ci, n, &pos);
     if (name) {
-      setobj2s(L, L->top, pos);
+      setobjs2s(L, L->top, pos);
       api_incr_top(L);
     }
   }
@@ -274,7 +274,7 @@ static int nextline (Proto *p, int currentline, int pc) {
 
 static void collectvalidlines (lua_State *L, Closure *f) {
   if (noLuaClosure(f)) {
-    setnilvalue(L->top);
+    setnilvalue(s2v(L->top));
     api_incr_top(L);
   }
   else {
@@ -283,7 +283,7 @@ static void collectvalidlines (lua_State *L, Closure *f) {
     Proto *p = f->l.p;
     int currentline = p->linedefined;
     Table *t = luaH_new(L);  /* new table to store active lines */
-    sethvalue(L, L->top, t);  /* push it on stack */
+    sethvalue2s(L, L->top, t);  /* push it on stack */
     api_incr_top(L);
     setbvalue(&v, 1);  /* boolean 'true' to be the value of all indices */
     for (i = 0; i < p->sizelineinfo; i++) {  /* for all lines with code */
@@ -359,25 +359,25 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
   int status;
   Closure *cl;
   CallInfo *ci;
-  StkId func;
+  TValue *func;
   lua_lock(L);
   swapextra(L);
   if (*what == '>') {
     ci = NULL;
-    func = L->top - 1;
+    func = s2v(L->top - 1);
     api_check(L, ttisfunction(func), "function expected");
     what++;  /* skip the '>' */
     L->top--;  /* pop function */
   }
   else {
     ci = ar->i_ci;
-    func = ci->func;
-    lua_assert(ttisfunction(ci->func));
+    func = s2v(ci->func);
+    lua_assert(ttisfunction(func));
   }
   cl = ttisclosure(func) ? clvalue(func) : NULL;
   status = auxgetinfo(L, what, ar, cl, ci);
   if (strchr(what, 'f')) {
-    setobjs2s(L, L->top, func);
+    setobj2s(L, L->top, func);
     api_incr_top(L);
   }
   swapextra(L);  /* correct before option 'L', which can raise a mem. error */
@@ -627,8 +627,8 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
 */
 static int isinstack (CallInfo *ci, const TValue *o) {
   StkId base = ci->func + 1;
-  ptrdiff_t i = o - base;
-  return (0 <= i && i < (ci->top - base) && base + i == o);
+  ptrdiff_t i = cast(StkId, o) - base;
+  return (0 <= i && i < (ci->top - base) && s2v(base + i) == o);
 }
 
 
@@ -659,7 +659,7 @@ static const char *varinfo (lua_State *L, const TValue *o) {
     kind = getupvalname(ci, o, &name);  /* check whether 'o' is an upvalue */
     if (!kind && isinstack(ci, o))  /* no? try a register */
       kind = getobjname(ci_func(ci)->p, currentpc(ci),
-                        cast_int(o - (ci->func + 1)), &name);
+                        cast_int(cast(StkId, o) - (ci->func + 1)), &name);
   }
   return (kind) ? luaO_pushfstring(L, " (%s '%s')", kind, name) : "";
 }

+ 20 - 18
ldo.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.c,v 2.159 2017/05/13 13:54:47 roberto Exp roberto $
+** $Id: ldo.c,v 2.160 2017/05/23 12:50:11 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -116,7 +116,7 @@ l_noret luaD_throw (lua_State *L, int errcode) {
     global_State *g = G(L);
     L->status = cast_byte(errcode);  /* mark it as dead */
     if (g->mainthread->errorJmp) {  /* main thread has a handler? */
-      setobj2s(L, g->mainthread->top++, L->top - 1);  /* copy error obj. */
+      setobjs2s(L, g->mainthread->top++, L->top - 1);  /* copy error obj. */
       luaD_throw(g->mainthread, errcode);  /* re-throw in main thread */
     }
     else {  /* no handler at all; abort */
@@ -155,12 +155,12 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
 ** Stack reallocation
 ** ===================================================================
 */
-static void correctstack (lua_State *L, TValue *oldstack) {
+static void correctstack (lua_State *L, StkId oldstack) {
   CallInfo *ci;
   UpVal *up;
   L->top = (L->top - oldstack) + L->stack;
   for (up = L->openupval; up != NULL; up = up->u.open.next)
-    up->v = (up->v - oldstack) + L->stack;
+    up->v = s2v((uplevel(up) - oldstack) + L->stack);
   for (ci = L->ci; ci != NULL; ci = ci->previous) {
     ci->top = (ci->top - oldstack) + L->stack;
     ci->func = (ci->func - oldstack) + L->stack;
@@ -173,13 +173,13 @@ static void correctstack (lua_State *L, TValue *oldstack) {
 
 
 void luaD_reallocstack (lua_State *L, int newsize) {
-  TValue *oldstack = L->stack;
+  StkId oldstack = L->stack;
   int lim = L->stacksize;
   lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE);
   lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK);
-  luaM_reallocvector(L, L->stack, L->stacksize, newsize, TValue);
+  luaM_reallocvector(L, L->stack, L->stacksize, newsize, StackValue);
   for (; lim < newsize; lim++)
-    setnilvalue(L->stack + lim); /* erase new segment */
+    setnilvalue(s2v(L->stack + lim)); /* erase new segment */
   L->stacksize = newsize;
   L->stack_last = L->stack + newsize - EXTRA_STACK;
   correctstack(L, oldstack);
@@ -294,10 +294,10 @@ static void callhook (lua_State *L, CallInfo *ci) {
 ** it. Raise an error if __call metafield is not a function.
 */
 static void tryfuncTM (lua_State *L, StkId func) {
-  const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL);
+  const TValue *tm = luaT_gettmbyobj(L, s2v(func), TM_CALL);
   StkId p;
   if (!ttisfunction(tm))
-    luaG_typeerror(L, func, "call");
+    luaG_typeerror(L, s2v(func), "call");
   /* Open a hole inside the stack at 'func' */
   for (p = L->top; p > func; p--)
     setobjs2s(L, p, p-1);
@@ -312,14 +312,15 @@ static void tryfuncTM (lua_State *L, StkId func) {
 ** expressions, multiple results for tail calls/single parameters)
 ** separated.
 */
-static int moveresults (lua_State *L, const TValue *firstResult, StkId res,
+static int moveresults (lua_State *L, StkId firstResult, StkId res,
                                       int nres, int wanted) {
   switch (wanted) {  /* handle typical cases separately */
     case 0: break;  /* nothing to move */
     case 1: {  /* one result needed */
       if (nres == 0)   /* no results? */
-        firstResult = luaO_nilobject;  /* adjust with nil */
-      setobjs2s(L, res, firstResult);  /* move it to proper place */
+        setnilvalue(s2v(res));  /* adjust with nil */
+      else
+        setobjs2s(L, res, firstResult);  /* move it to proper place */
       break;
     }
     case LUA_MULTRET: {
@@ -339,7 +340,7 @@ static int moveresults (lua_State *L, const TValue *firstResult, StkId res,
         for (i = 0; i < nres; i++)  /* move all results to correct place */
           setobjs2s(L, res + i, firstResult + i);
         for (; i < wanted; i++)  /* complete wanted number of results */
-          setnilvalue(res + i);
+          setnilvalue(s2v(res + i));
       }
       break;
     }
@@ -385,13 +386,14 @@ int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) {
 */
 int luaD_precall (lua_State *L, StkId func, int nresults) {
   lua_CFunction f;
+  TValue *funcv = s2v(func);
   CallInfo *ci;
-  switch (ttype(func)) {
+  switch (ttype(funcv)) {
     case LUA_TCCL:  /* C closure */
-      f = clCvalue(func)->f;
+      f = clCvalue(funcv)->f;
       goto Cfunc;
     case LUA_TLCF:  /* light C function */
-      f = fvalue(func);
+      f = fvalue(funcv);
      Cfunc: {
       int n;  /* number of returns */
       checkstackp(L, LUA_MINSTACK, func);  /* ensure minimum stack size */
@@ -411,12 +413,12 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
       return 1;
     }
     case LUA_TLCL: {  /* Lua function: prepare its call */
-      Proto *p = clLvalue(func)->p;
+      Proto *p = clLvalue(funcv)->p;
       int n = cast_int(L->top - func) - 1;  /* number of real arguments */
       int fsize = p->maxstacksize;  /* frame size */
       checkstackp(L, fsize, func);
       for (; n < p->numparams - p->is_vararg; n++)
-        setnilvalue(L->top++);  /* complete missing arguments */
+        setnilvalue(s2v(L->top++));  /* complete missing arguments */
       if (p->is_vararg)
         luaT_adjustvarargs(L, p, n);
       ci = next_ci(L);  /* now 'enter' new function */

+ 2 - 2
ldo.h

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.h,v 2.29 2015/12/21 13:02:14 roberto Exp roberto $
+** $Id: ldo.h,v 2.30 2017/05/13 12:57:20 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -30,7 +30,7 @@
 
 
 #define savestack(L,p)		((char *)(p) - (char *)L->stack)
-#define restorestack(L,n)	((TValue *)((char *)L->stack + (n)))
+#define restorestack(L,n)	((StkId)((char *)L->stack + (n)))
 
 
 /* macro to check stack size, preserving 'p' */

+ 6 - 6
lfunc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lfunc.c,v 2.49 2017/05/24 18:54:54 roberto Exp roberto $
+** $Id: lfunc.c,v 2.50 2017/06/27 11:35:31 roberto Exp roberto $
 ** Auxiliary functions to manipulate prototypes and closures
 ** See Copyright Notice in lua.h
 */
@@ -61,9 +61,8 @@ UpVal *luaF_findupval (lua_State *L, StkId level) {
   UpVal *p;
   UpVal *uv;
   lua_assert(isintwups(L) || L->openupval == NULL);
-  while ((p = *pp) != NULL && p->v >= level) {
-    lua_assert(upisopen(p));
-    if (p->v == level && !isdead(G(L), p))  /* corresponding upvalue? */
+  while ((p = *pp) != NULL && uplevel(p) >= level) {
+    if (uplevel(p) == level && !isdead(G(L), p))  /* corresponding upvalue? */
       return p;  /* return it */
     pp = &p->u.open.next;
   }
@@ -75,7 +74,7 @@ UpVal *luaF_findupval (lua_State *L, StkId level) {
   if (p)
     p->u.open.previous = &uv->u.open.next;
   *pp = uv;
-  uv->v = level;  /* current value lives in the stack */
+  uv->v = s2v(level);  /* current value lives in the stack */
   if (!isintwups(L)) {  /* thread not in list of threads with upvalues? */
     L->twups = G(L)->twups;  /* link it to the list */
     G(L)->twups = L;
@@ -94,7 +93,8 @@ void luaF_unlinkupval (UpVal *uv) {
 
 void luaF_close (lua_State *L, StkId level) {
   UpVal *uv;
-  while (L->openupval != NULL && (uv = L->openupval)->v >= level) {
+  while (L->openupval != NULL &&
+        (uv = L->openupval, uplevel(uv) >= level)) {
     TValue *slot = &uv->u.value;  /* new position for value */
     luaF_unlinkupval(uv);
     setobj(L, slot, uv->v);  /* move value to upvalue slot */

+ 4 - 1
lfunc.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lfunc.h,v 2.16 2017/04/11 18:41:09 roberto Exp roberto $
+** $Id: lfunc.h,v 2.17 2017/05/04 13:32:01 roberto Exp roberto $
 ** Auxiliary functions to manipulate prototypes and closures
 ** See Copyright Notice in lua.h
 */
@@ -32,6 +32,9 @@
 #define upisopen(up)	((up)->v != &(up)->u.value)
 
 
+#define uplevel(up)	check_exp(upisopen(up), cast(StkId, (up)->v))
+
+
 /*
 ** maximum number of misses before giving up the cache of closures
 ** in prototypes

+ 5 - 5
lgc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.c,v 2.231 2017/06/09 16:48:44 roberto Exp roberto $
+** $Id: lgc.c,v 2.232 2017/06/12 14:21:44 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -575,11 +575,11 @@ static int traversethread (global_State *g, lua_State *th) {
   lua_assert(g->gcstate == GCSatomic ||
              th->openupval == NULL || isintwups(th));
   for (; o < th->top; o++)  /* mark live elements in the stack */
-    markvalue(g, o);
+    markvalue(g, s2v(o));
   if (g->gcstate == GCSatomic) {  /* final traversal? */
     StkId lim = th->stack + th->stacksize;  /* real end of stack */
     for (; o < lim; o++)  /* clear not-marked stack slice */
-      setnilvalue(o);
+      setnilvalue(s2v(o));
     /* 'remarkupvals' may have removed thread from 'twups' list */
     if (!isintwups(th) && th->openupval != NULL) {
       th->twups = g->twups;  /* link it back to the list */
@@ -872,8 +872,8 @@ static void GCTM (lua_State *L, int propagateerrors) {
     g->gcrunning = running;  /* restore state */
     if (status != LUA_OK && propagateerrors) {  /* error while running __gc? */
       if (status == LUA_ERRRUN) {  /* is there an error object? */
-        const char *msg = (ttisstring(L->top - 1))
-                            ? svalue(L->top - 1)
+        const char *msg = (ttisstring(s2v(L->top - 1)))
+                            ? svalue(s2v(L->top - 1))
                             : "no message";
         luaO_pushfstring(L, "error in __gc metamethod (%s)", msg);
         status = LUA_ERRGCMM;  /* error in __gc metamethod */

+ 2 - 2
llex.c

@@ -1,5 +1,5 @@
 /*
-** $Id: llex.c,v 2.96 2016/05/02 14:02:12 roberto Exp roberto $
+** $Id: llex.c,v 2.97 2017/06/09 16:48:44 roberto Exp roberto $
 ** Lexical Analyzer
 ** See Copyright Notice in lua.h
 */
@@ -129,7 +129,7 @@ TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
   TValue *o;  /* entry for 'str' */
   TString *ts = luaS_newlstr(L, str, l);  /* create new string */
   setsvalue2s(L, L->top++, ts);  /* temporarily anchor it in stack */
-  o = luaH_set(L, ls->h, L->top - 1);
+  o = luaH_set(L, ls->h, s2v(L->top - 1));
   if (ttisnil(o)) {  /* not in use yet? */
     /* boolean value does not need GC barrier;
        table is not a metatable, so it does not need to invalidate cache */

+ 26 - 19
lobject.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lobject.c,v 2.114 2017/04/19 16:34:35 roberto Exp roberto $
+** $Id: lobject.c,v 2.115 2017/05/24 13:47:11 roberto Exp roberto $
 ** Some generic functions over Lua objects
 ** See Copyright Notice in lua.h
 */
@@ -120,8 +120,8 @@ static lua_Number numarith (lua_State *L, int op, lua_Number v1,
 }
 
 
-void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2,
-                 TValue *res) {
+int luaO_rawarith (lua_State *L, int op, const TValue *p1, const TValue *p2,
+                   TValue *res) {
   switch (op) {
     case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR:
     case LUA_OPSHL: case LUA_OPSHR:
@@ -129,33 +129,40 @@ void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2,
       lua_Integer i1; lua_Integer i2;
       if (tointeger(p1, &i1) && tointeger(p2, &i2)) {
         setivalue(res, intarith(L, op, i1, i2));
-        return;
+        return 1;
       }
-      else break;  /* go to the end */
+      else return 0;  /* fail */
     }
     case LUA_OPDIV: case LUA_OPPOW: {  /* operate only on floats */
       lua_Number n1; lua_Number n2;
       if (tonumber(p1, &n1) && tonumber(p2, &n2)) {
         setfltvalue(res, numarith(L, op, n1, n2));
-        return;
+        return 1;
       }
-      else break;  /* go to the end */
+      else return 0;  /* fail */
     }
     default: {  /* other operations */
       lua_Number n1; lua_Number n2;
       if (ttisinteger(p1) && ttisinteger(p2)) {
         setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2)));
-        return;
+        return 1;
       }
       else if (tonumber(p1, &n1) && tonumber(p2, &n2)) {
         setfltvalue(res, numarith(L, op, n1, n2));
-        return;
+        return 1;
       }
-      else break;  /* go to the end */
+      else return 0;  /* fail */
     }
   }
-  /* could not perform raw operation; try metamethod */
-  luaT_trybinTM(L, p1, p2, res, cast(TMS, (op - LUA_OPADD) + TM_ADD));
+}
+
+
+void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2,
+                 StkId res) {
+  if (!luaO_rawarith(L, op, p1, p2, s2v(res))) {
+    /* could not perform raw operation; try metamethod */
+    luaT_trybinTM(L, p1, p2, res, cast(TMS, (op - LUA_OPADD) + TM_ADD));
+  }
 }
 
 
@@ -367,7 +374,7 @@ int luaO_utf8esc (char *buff, unsigned long x) {
 /*
 ** Convert a number object to a string
 */
-void luaO_tostring (lua_State *L, StkId obj) {
+void luaO_tostring (lua_State *L, TValue *obj) {
   char buff[MAXNUMBER2STR];
   size_t len;
   lua_assert(ttisnumber(obj));
@@ -382,7 +389,7 @@ void luaO_tostring (lua_State *L, StkId obj) {
     }
 #endif
   }
-  setsvalue2s(L, obj, luaS_newlstr(L, buff, len));
+  setsvalue(L, obj, luaS_newlstr(L, buff, len));
 }
 
 
@@ -418,18 +425,18 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
         break;
       }
       case 'd': {  /* an 'int' */
-        setivalue(L->top, va_arg(argp, int));
+        setivalue(s2v(L->top), va_arg(argp, int));
         goto top2str;
       }
       case 'I': {  /* a 'lua_Integer' */
-        setivalue(L->top, cast(lua_Integer, va_arg(argp, l_uacInt)));
+        setivalue(s2v(L->top), cast(lua_Integer, va_arg(argp, l_uacInt)));
         goto top2str;
       }
       case 'f': {  /* a 'lua_Number' */
-        setfltvalue(L->top, cast_num(va_arg(argp, l_uacNumber)));
+        setfltvalue(s2v(L->top), cast_num(va_arg(argp, l_uacNumber)));
       top2str:  /* convert the top element to a string */
         luaD_inctop(L);
-        luaO_tostring(L, L->top - 1);
+        luaO_tostring(L, s2v(L->top - 1));
         break;
       }
       case 'p': {  /* a pointer */
@@ -460,7 +467,7 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
   luaD_checkstack(L, 1);
   pushstr(L, fmt, strlen(fmt));
   if (n > 0) luaV_concat(L, n + 1);
-  return svalue(L->top - 1);
+  return svalue(s2v(L->top - 1));
 }
 
 

+ 22 - 11
lobject.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lobject.h,v 2.123 2017/06/12 14:21:44 roberto Exp roberto $
+** $Id: lobject.h,v 2.124 2017/06/27 11:35:31 roberto Exp roberto $
 ** Type definitions for Lua objects
 ** See Copyright Notice in lua.h
 */
@@ -110,7 +110,7 @@ typedef union Value {
 #define TValuefields	Value value_; lu_byte tt_
 
 
-typedef struct lua_TValue {
+typedef struct TValue {
   TValuefields;
 } TValue;
 
@@ -282,13 +282,15 @@ typedef struct lua_TValue {
 ** different types of assignments, according to destination
 */
 
-/* from stack to (same) stack */
-#define setobjs2s	setobj
+/* from stack to stack */
+#define setobjs2s(L,o1,o2)	setobj(L,s2v(o1),s2v(o2))
 /* to stack (not from same stack) */
-#define setobj2s	setobj
-#define setsvalue2s	setsvalue
-#define sethvalue2s	sethvalue
-#define setptvalue2s	setptvalue
+#define setobj2s(L,o1,o2)	setobj(L,s2v(o1),o2)
+#define setsvalue2s(L,o,s)	setsvalue(L,s2v(o),s)
+#define sethvalue2s(L,o,h)	sethvalue(L,s2v(o),h)
+#define setthvalue2s(L,o,t)	setthvalue(L,s2v(o),t)
+#define setptvalue2s(L,o,p)	setptvalue(L,s2v(o),p)
+#define setclLvalue2s(L,o,cl)	setclLvalue(L,s2v(o),cl)
 /* from table to same table */
 #define setobjt2t	setobj
 /* to new object */
@@ -307,9 +309,16 @@ typedef struct lua_TValue {
 */
 
 
-typedef TValue *StkId;  /* index to stack elements */
+typedef union StackValue {
+  TValue val;
+} StackValue;
 
 
+typedef StackValue *StkId;  /* index to stack elements */
+
+/* convert a 'StackValue' to a 'TValue' */
+#define s2v(o)	(&(o)->val)
+
 
 
 /*
@@ -620,11 +629,13 @@ LUAI_FUNC int luaO_int2fb (unsigned int x);
 LUAI_FUNC int luaO_fb2int (int x);
 LUAI_FUNC int luaO_utf8esc (char *buff, unsigned long x);
 LUAI_FUNC int luaO_ceillog2 (unsigned int x);
+LUAI_FUNC int luaO_rawarith (lua_State *L, int op, const TValue *p1,
+                             const TValue *p2, TValue *res);
 LUAI_FUNC void luaO_arith (lua_State *L, int op, const TValue *p1,
-                           const TValue *p2, TValue *res);
+                           const TValue *p2, StkId res);
 LUAI_FUNC size_t luaO_str2num (const char *s, TValue *o);
 LUAI_FUNC int luaO_hexavalue (int c);
-LUAI_FUNC void luaO_tostring (lua_State *L, StkId obj);
+LUAI_FUNC void luaO_tostring (lua_State *L, TValue *obj);
 LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
                                                        va_list argp);
 LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);

+ 3 - 3
lparser.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.c,v 2.159 2017/05/13 12:57:20 roberto Exp roberto $
+** $Id: lparser.c,v 2.160 2017/06/27 11:35:31 roberto Exp roberto $
 ** Lua Parser
 ** See Copyright Notice in lua.h
 */
@@ -1650,10 +1650,10 @@ LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
   LexState lexstate;
   FuncState funcstate;
   LClosure *cl = luaF_newLclosure(L, 1);  /* create main closure */
-  setclLvalue(L, L->top, cl);  /* anchor it (to avoid being collected) */
+  setclLvalue2s(L, L->top, cl);  /* anchor it (to avoid being collected) */
   luaD_inctop(L);
   lexstate.h = luaH_new(L);  /* create table for scanner */
-  sethvalue(L, L->top, lexstate.h);  /* anchor it */
+  sethvalue2s(L, L->top, lexstate.h);  /* anchor it */
   luaD_inctop(L);
   funcstate.f = cl->p = luaF_newproto(L);
   funcstate.f->source = luaS_new(L, name);  /* create and anchor TString */

+ 5 - 5
lstate.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.c,v 2.139 2017/05/04 13:32:01 roberto Exp roberto $
+** $Id: lstate.c,v 2.140 2017/05/26 19:14:29 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -143,10 +143,10 @@ void luaE_shrinkCI (lua_State *L) {
 static void stack_init (lua_State *L1, lua_State *L) {
   int i; CallInfo *ci;
   /* initialize stack array */
-  L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue);
+  L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, StackValue);
   L1->stacksize = BASIC_STACK_SIZE;
   for (i = 0; i < BASIC_STACK_SIZE; i++)
-    setnilvalue(L1->stack + i);  /* erase new stack */
+    setnilvalue(s2v(L1->stack + i));  /* erase new stack */
   L1->top = L1->stack;
   L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK;
   /* initialize first ci */
@@ -154,7 +154,7 @@ static void stack_init (lua_State *L1, lua_State *L) {
   ci->next = ci->previous = NULL;
   ci->callstatus = 0;
   ci->func = L1->top;
-  setnilvalue(L1->top++);  /* 'function' entry for this 'ci' */
+  setnilvalue(s2v(L1->top++));  /* 'function' entry for this 'ci' */
   ci->top = L1->top + LUA_MINSTACK;
   L1->ci = ci;
 }
@@ -258,7 +258,7 @@ LUA_API lua_State *lua_newthread (lua_State *L) {
   L1->next = g->allgc;
   g->allgc = obj2gco(L1);
   /* anchor it on L stack */
-  setthvalue(L, L->top, L1);
+  setthvalue2s(L, L->top, L1);
   api_incr_top(L);
   preinit_thread(L1, g);
   L1->hookmask = L->hookmask;

+ 6 - 6
ltable.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltable.c,v 2.123 2017/06/09 16:48:44 roberto Exp roberto $
+** $Id: ltable.c,v 2.124 2017/06/12 14:21:44 roberto Exp roberto $
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 */
@@ -211,7 +211,7 @@ static unsigned int arrayindex (lua_Integer k) {
 ** elements in the array part, then elements in the hash part. The
 ** beginning of a traversal is signaled by 0.
 */
-static unsigned int findindex (lua_State *L, Table *t, StkId key) {
+static unsigned int findindex (lua_State *L, Table *t, TValue *key) {
   unsigned int i;
   if (ttisnil(key)) return 0;  /* first iteration */
   i = ttisinteger(key) ? arrayindex(ivalue(key)) : 0;
@@ -229,18 +229,18 @@ static unsigned int findindex (lua_State *L, Table *t, StkId key) {
 
 
 int luaH_next (lua_State *L, Table *t, StkId key) {
-  unsigned int i = findindex(L, t, key);  /* find original element */
+  unsigned int i = findindex(L, t, s2v(key));  /* find original element */
   for (; i < t->sizearray; i++) {  /* try first array part */
     if (!ttisnil(&t->array[i])) {  /* a non-nil value? */
-      setivalue(key, i + 1);
-      setobj2s(L, key+1, &t->array[i]);
+      setivalue(s2v(key), i + 1);
+      setobj2s(L, key + 1, &t->array[i]);
       return 1;
     }
   }
   for (i -= t->sizearray; cast_int(i) < sizenode(t); i++) {  /* hash part */
     if (!ttisnil(gval(gnode(t, i)))) {  /* a non-nil value? */
       Node *n = gnode(t, i);
-      getnodekey(L, key, n);
+      getnodekey(L, s2v(key), n);
       setobj2s(L, key + 1, gval(n));
       return 1;
     }

+ 4 - 4
ltests.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltests.c,v 2.221 2017/06/27 11:35:31 roberto Exp roberto $
+** $Id: ltests.c,v 2.222 2017/06/27 18:32:49 roberto Exp roberto $
 ** Internal Module for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 */
@@ -46,7 +46,7 @@ void *l_Trick = 0;
 int islocked = 0;
 
 
-#define obj_at(L,k)	(L->ci->func + (k))
+#define obj_at(L,k)	s2v(L->ci->func + (k))
 
 
 static int runC (lua_State *L, lua_State *L1, const char *pc);
@@ -316,7 +316,7 @@ static int lua_checkpc (lua_State *L, CallInfo *ci) {
     StkId f = (L->status != LUA_YIELD || ci != L->ci)
               ? ci->func
               : restorestack(L, ci->extra);
-    Proto *p = clLvalue(f)->p;
+    Proto *p = clLvalue(s2v(f))->p;
     return p->code <= ci->u.l.savedpc &&
            ci->u.l.savedpc <= p->code + p->sizecode;
   }
@@ -336,7 +336,7 @@ static void checkstack (global_State *g, lua_State *L1) {
   }
   if (L1->stack) {  /* complete thread? */
     for (o = L1->stack; o < L1->stack_last + EXTRA_STACK; o++)
-      checkliveness(L1, o);  /* entire stack must have valid values */
+      checkliveness(L1, s2v(o));  /* entire stack must have valid values */
   }
   else lua_assert(L1->stacksize == 0);
 }

+ 29 - 17
ltm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltm.c,v 2.40 2017/05/08 15:57:23 roberto Exp roberto $
+** $Id: ltm.c,v 2.41 2017/05/13 12:57:20 roberto Exp roberto $
 ** Tag methods
 ** See Copyright Notice in lua.h
 */
@@ -100,24 +100,36 @@ const char *luaT_objtypename (lua_State *L, const TValue *o) {
 
 
 void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
-                  const TValue *p2, TValue *p3, int hasres) {
-  ptrdiff_t result = savestack(L, p3);
+                  const TValue *p2, const TValue *p3) {
+  StkId func = L->top;
+  setobj2s(L, func, f);  /* push function (assume EXTRA_STACK) */
+  setobj2s(L, func + 1, p1);  /* 1st argument */
+  setobj2s(L, func + 2, p2);  /* 2nd argument */
+  setobj2s(L, func + 3, p3);  /* 3rd argument */
+  L->top += 4;
+  /* metamethod may yield only when called from Lua code */
+  if (isLua(L->ci))
+    luaD_call(L, func, 0);
+  else
+    luaD_callnoyield(L, func, 0);
+}
+
+
+void luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1,
+                     const TValue *p2, StkId res) {
+  ptrdiff_t result = savestack(L, res);
   StkId func = L->top;
   setobj2s(L, func, f);  /* push function (assume EXTRA_STACK) */
   setobj2s(L, func + 1, p1);  /* 1st argument */
   setobj2s(L, func + 2, p2);  /* 2nd argument */
   L->top += 3;
-  if (!hasres)  /* no result? 'p3' is third argument */
-    setobj2s(L, L->top++, p3);  /* 3rd argument */
   /* metamethod may yield only when called from Lua code */
   if (isLua(L->ci))
-    luaD_call(L, func, hasres);
+    luaD_call(L, func, 1);
   else
-    luaD_callnoyield(L, func, hasres);
-  if (hasres) {  /* if has result, move it to its place */
-    p3 = restorestack(L, result);
-    setobjs2s(L, p3, --L->top);
-  }
+    luaD_callnoyield(L, func, 1);
+  res = restorestack(L, result);
+  setobjs2s(L, res, --L->top);  /* more result to its place */
 }
 
 
@@ -127,7 +139,7 @@ static int callbinTM (lua_State *L, const TValue *p1, const TValue *p2,
   if (ttisnil(tm))
     tm = luaT_gettmbyobj(L, p2, event);  /* try second operand */
   if (ttisnil(tm)) return 0;
-  luaT_callTM(L, tm, p1, p2, res, 1);
+  luaT_callTMres(L, tm, p1, p2, res);
   return 1;
 }
 
@@ -160,7 +172,7 @@ int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2,
   if (!callbinTM(L, p1, p2, L->top, event))
     return -1;  /* no metamethod */
   else
-    return !l_isfalse(L->top);
+    return !l_isfalse(s2v(L->top));
 }
 
 
@@ -171,19 +183,19 @@ void luaT_adjustvarargs (lua_State *L, Proto *p, int actual) {
   int nfixparams = p->numparams - 1;  /* number of fixed parameters */
   actual -= nfixparams;  /* number of extra arguments */
   vtab = luaH_new(L);  /* create vararg table */
-  sethvalue(L, L->top, vtab);  /* anchor it for resizing */
+  sethvalue2s(L, L->top, vtab);  /* anchor it for resizing */
   L->top++;  /* space ensured by caller */
   luaH_resize(L, vtab, actual, 1);
   for (i = 0; i < actual; i++)  /* put extra arguments into vararg table */
-    setobj2n(L, &vtab->array[i], L->top - actual + i - 1);
+    setobj2n(L, &vtab->array[i], s2v(L->top - actual + i - 1));
   setsvalue(L, &nname, luaS_newliteral(L, "n"));  /* get field 'n' */
   setivalue(luaH_set(L, vtab, &nname), actual);  /* store counter there */
   L->top -= actual;  /* remove extra elements from the stack */
-  sethvalue(L, L->top - 1, vtab);  /* move table to new top */
+  sethvalue2s(L, L->top - 1, vtab);  /* move table to new top */
 }
 
 
-void luaT_getvarargs (lua_State *L, StkId t, StkId where, int wanted) {
+void luaT_getvarargs (lua_State *L, TValue *t, StkId where, int wanted) {
   if (!ttistable(t))
     luaG_runerror(L, "'vararg' parameter is not a table");
   else {

+ 5 - 3
ltm.h

@@ -1,5 +1,5 @@
 /*
-** $Id: ltm.h,v 2.23 2017/05/08 15:57:23 roberto Exp roberto $
+** $Id: ltm.h,v 2.24 2017/05/13 12:57:20 roberto Exp roberto $
 ** Tag methods
 ** See Copyright Notice in lua.h
 */
@@ -63,14 +63,16 @@ LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o,
 LUAI_FUNC void luaT_init (lua_State *L);
 
 LUAI_FUNC void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
-                            const TValue *p2, TValue *p3, int hasres);
+                            const TValue *p2, const TValue *p3);
+LUAI_FUNC void luaT_callTMres (lua_State *L, const TValue *f,
+                            const TValue *p1, const TValue *p2, StkId p3);
 LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
                               StkId res, TMS event);
 LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1,
                                 const TValue *p2, TMS event);
 
 LUAI_FUNC void luaT_adjustvarargs (lua_State *L, Proto *p, int actual);
-LUAI_FUNC void luaT_getvarargs (lua_State *L, StkId t, StkId where,
+LUAI_FUNC void luaT_getvarargs (lua_State *L, TValue *t, StkId where,
                                 int wanted);
 
 

+ 2 - 2
lundump.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lundump.c,v 2.45 2017/06/27 11:35:31 roberto Exp roberto $
+** $Id: lundump.c,v 2.46 2017/06/27 14:21:12 roberto Exp roberto $
 ** load precompiled Lua chunks
 ** See Copyright Notice in lua.h
 */
@@ -283,7 +283,7 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) {
   S.Z = Z;
   checkHeader(&S);
   cl = luaF_newLclosure(L, LoadByte(&S));
-  setclLvalue(L, L->top, cl);
+  setclLvalue2s(L, L->top, cl);
   luaD_inctop(L);
   cl->p = luaF_newproto(L);
   LoadFunction(&S, cl->p, NULL);

+ 107 - 102
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 2.286 2017/06/01 20:22:33 roberto Exp roberto $
+** $Id: lvm.c,v 2.287 2017/06/09 19:16:41 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -172,13 +172,13 @@ void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
       lua_assert(ttisnil(slot));
       tm = fasttm(L, hvalue(t)->metatable, TM_INDEX);  /* table's metamethod */
       if (tm == NULL) {  /* no metamethod? */
-        setnilvalue(val);  /* result is nil */
+        setnilvalue(s2v(val));  /* result is nil */
         return;
       }
       /* else will try the metamethod */
     }
     if (ttisfunction(tm)) {  /* is metamethod a function? */
-      luaT_callTM(L, tm, t, key, val, 1);  /* call it */
+      luaT_callTMres(L, tm, t, key, val);  /* call it */
       return;
     }
     t = tm;  /* else try to access 'tm[key]' */
@@ -200,7 +200,7 @@ void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
 ** would have done the job.)
 */
 void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
-                     StkId val, const TValue *slot) {
+                     TValue *val, const TValue *slot) {
   int loop;  /* counter to avoid infinite loops */
   for (loop = 0; loop < MAXTAGLOOP; loop++) {
     const TValue *tm;  /* '__newindex' metamethod */
@@ -225,7 +225,7 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
     }
     /* try the metamethod */
     if (ttisfunction(tm)) {
-      luaT_callTM(L, tm, t, key, val, 0);
+      luaT_callTM(L, tm, t, key, val);
       return;
     }
     t = tm;  /* else repeat assignment over 'tm' */
@@ -446,8 +446,8 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
   }
   if (tm == NULL)  /* no TM? */
     return 0;  /* objects are different */
-  luaT_callTM(L, tm, t1, t2, L->top, 1);  /* call TM */
-  return !l_isfalse(L->top);
+  luaT_callTMres(L, tm, t1, t2, L->top);  /* call TM */
+  return !l_isfalse(s2v(L->top));
 }
 
 
@@ -461,8 +461,8 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
 static void copy2buff (StkId top, int n, char *buff) {
   size_t tl = 0;  /* size already copied */
   do {
-    size_t l = vslen(top - n);  /* length of string being copied */
-    memcpy(buff + tl, svalue(top - n), l * sizeof(char));
+    size_t l = vslen(s2v(top - n));  /* length of string being copied */
+    memcpy(buff + tl, svalue(s2v(top - n)), l * sizeof(char));
     tl += l;
   } while (--n > 0);
 }
@@ -477,20 +477,21 @@ void luaV_concat (lua_State *L, int total) {
   do {
     StkId top = L->top;
     int n = 2;  /* number of elements handled in this pass (at least 2) */
-    if (!(ttisstring(top-2) || cvt2str(top-2)) || !tostring(L, top-1))
-      luaT_trybinTM(L, top-2, top-1, top-2, TM_CONCAT);
-    else if (isemptystr(top - 1))  /* second operand is empty? */
-      cast_void(tostring(L, top - 2));  /* result is first operand */
-    else if (isemptystr(top - 2)) {  /* first operand is an empty string? */
+    if (!(ttisstring(s2v(top - 2)) || cvt2str(s2v(top - 2))) ||
+        !tostring(L, s2v(top - 1)))
+      luaT_trybinTM(L, s2v(top - 2), s2v(top - 1), top - 2, TM_CONCAT);
+    else if (isemptystr(s2v(top - 1)))  /* second operand is empty? */
+      cast_void(tostring(L, s2v(top - 2)));  /* result is first operand */
+    else if (isemptystr(s2v(top - 2))) {  /* first operand is empty string? */
       setobjs2s(L, top - 2, top - 1);  /* result is second op. */
     }
     else {
       /* at least two non-empty string values; get as many as possible */
-      size_t tl = vslen(top - 1);
+      size_t tl = vslen(s2v(top - 1));
       TString *ts;
       /* collect total length and number of strings */
-      for (n = 1; n < total && tostring(L, top - n - 1); n++) {
-        size_t l = vslen(top - n - 1);
+      for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) {
+        size_t l = vslen(s2v(top - n - 1));
         if (l >= (MAX_SIZE/sizeof(char)) - tl)
           luaG_runerror(L, "string length overflow");
         tl += l;
@@ -522,15 +523,15 @@ void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
       Table *h = hvalue(rb);
       tm = fasttm(L, h->metatable, TM_LEN);
       if (tm) break;  /* metamethod? break switch to call it */
-      setivalue(ra, luaH_getn(h));  /* else primitive len */
+      setivalue(s2v(ra), luaH_getn(h));  /* else primitive len */
       return;
     }
     case LUA_TSHRSTR: {
-      setivalue(ra, tsvalue(rb)->shrlen);
+      setivalue(s2v(ra), tsvalue(rb)->shrlen);
       return;
     }
     case LUA_TLNGSTR: {
-      setivalue(ra, tsvalue(rb)->u.lnglen);
+      setivalue(s2v(ra), tsvalue(rb)->u.lnglen);
       return;
     }
     default: {  /* try metamethod */
@@ -540,7 +541,7 @@ void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
       break;
     }
   }
-  luaT_callTM(L, tm, rb, rb, ra, 1);
+  luaT_callTMres(L, tm, rb, rb, ra);
 }
 
 
@@ -615,7 +616,7 @@ static LClosure *getcached (Proto *p, UpVal **encup, StkId base) {
     Upvaldesc *uv = p->upvalues;
     int i;
     for (i = 0; i < nup; i++) {  /* check whether it has right upvalues */
-      TValue *v = uv[i].instack ? base + uv[i].idx : encup[uv[i].idx]->v;
+      TValue *v = uv[i].instack ? s2v(base + uv[i].idx) : encup[uv[i].idx]->v;
       if (c->upvals[i]->v != v)
         return NULL;  /* wrong upvalue; cannot reuse closure */
     }
@@ -636,7 +637,7 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
   int i;
   LClosure *ncl = luaF_newLclosure(L, nup);
   ncl->p = p;
-  setclLvalue(L, ra, ncl);  /* anchor new closure in stack */
+  setclLvalue2s(L, ra, ncl);  /* anchor new closure in stack */
   for (i = 0; i < nup; i++) {  /* fill in its upvalues */
     if (uv[i].instack)  /* upvalue refers to local variable? */
       ncl->upvals[i] = luaF_findupval(L, base + uv[i].idx);
@@ -674,7 +675,7 @@ void luaV_finishOp (lua_State *L) {
       break;
     }
     case OP_LE: case OP_LT: case OP_EQ: {
-      int res = !l_isfalse(L->top - 1);
+      int res = !l_isfalse(s2v(L->top - 1));
       L->top--;
       if (ci->callstatus & CIST_LEQ) {  /* "<=" using "<" instead? */
         lua_assert(op == OP_LE);
@@ -734,13 +735,15 @@ void luaV_finishOp (lua_State *L) {
 
 #define RA(i)	(base+GETARG_A(i))
 #define RB(i)	check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_Br(i))
+#define vRB(i)	s2v(RB(i))
 #define KB(i)	check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_B(i))
 #define RC(i)	check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i))
+#define vRC(i)	s2v(RC(i))
 #define KC(i)	check_exp(getCMode(GET_OPCODE(i)) == OpArgK, k+GETARG_C(i))
 #define RKB(i)	check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \
-	(GETARG_Bk(i)) ? k + GETARG_Br(i) : base + GETARG_Br(i))
+	(GETARG_Bk(i)) ? k + GETARG_Br(i) : s2v(base + GETARG_Br(i)))
 #define RKC(i)	check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \
-	(GETARG_Ck(i)) ? k + GETARG_Cr(i) : base + GETARG_Cr(i))
+	(GETARG_Ck(i)) ? k + GETARG_Cr(i) : s2v(base + GETARG_Cr(i)))
 
 
 
@@ -803,7 +806,7 @@ void luaV_execute (lua_State *L) {
   ci->callstatus |= CIST_FRESH;  /* fresh invocation of 'luaV_execute" */
  newframe:  /* reentry point when frame changes (call/return) */
   lua_assert(ci == L->ci);
-  cl = clLvalue(ci->func);  /* local reference to function's closure */
+  cl = clLvalue(s2v(ci->func));  /* local reference to function's closure */
   k = cl->p->k;  /* local reference to function's constant table */
   updatemask(L);
   base = ci->func + 1;
@@ -827,7 +830,7 @@ void luaV_execute (lua_State *L) {
       }
       vmcase(OP_LOADI) {
         lua_Integer b = GETARG_sBx(i);
-        setivalue(ra, b);
+        setivalue(s2v(ra), b);
         vmbreak;
       }
       vmcase(OP_LOADKX) {
@@ -838,14 +841,14 @@ void luaV_execute (lua_State *L) {
         vmbreak;
       }
       vmcase(OP_LOADBOOL) {
-        setbvalue(ra, GETARG_B(i));
+        setbvalue(s2v(ra), GETARG_B(i));
         if (GETARG_C(i)) pc++;  /* skip next instruction (if C) */
         vmbreak;
       }
       vmcase(OP_LOADNIL) {
         int b = GETARG_B(i);
         do {
-          setnilvalue(ra++);
+          setnilvalue(s2v(ra++));
         } while (b--);
         vmbreak;
       }
@@ -856,8 +859,8 @@ void luaV_execute (lua_State *L) {
       }
       vmcase(OP_SETUPVAL) {
         UpVal *uv = cl->upvals[GETARG_B(i)];
-        setobj(L, uv->v, ra);
-        luaC_barrier(L, uv, ra);
+        setobj(L, uv->v, s2v(ra));
+        luaC_barrier(L, uv, s2v(ra));
         vmbreak;
       }
       vmcase(OP_GETTABUP) {
@@ -873,8 +876,8 @@ void luaV_execute (lua_State *L) {
       }
       vmcase(OP_GETTABLE) {
         const TValue *slot;
-        StkId rb = RB(i);
-        TValue *rc = RC(i);
+        TValue *rb = vRB(i);
+        TValue *rc = vRC(i);
         lua_Unsigned n;
         if (ttisinteger(rc)  /* fast track for integers? */
             ? (n = ivalue(rc), luaV_fastgeti(L, rb, n, slot))
@@ -887,7 +890,7 @@ void luaV_execute (lua_State *L) {
       }
       vmcase(OP_GETI) {
         const TValue *slot;
-        StkId rb = RB(i);
+        TValue *rb = vRB(i);
         int c = GETARG_C(i);
         if (luaV_fastgeti(L, rb, c, slot)) {
           setobj2s(L, ra, slot);
@@ -901,7 +904,7 @@ void luaV_execute (lua_State *L) {
       }
       vmcase(OP_GETFIELD) {
         const TValue *slot;
-        StkId rb = RB(i);
+        TValue *rb = vRB(i);
         TValue *rc = KC(i);
         TString *key = tsvalue(rc);  /* key must be a string */
         if (luaV_fastget(L, rb, key, slot, luaH_getshortstr)) {
@@ -925,29 +928,29 @@ void luaV_execute (lua_State *L) {
       }
       vmcase(OP_SETTABLE) {
         const TValue *slot;
-        TValue *rb = RB(i);  /* key (table is in 'ra') */
+        TValue *rb = vRB(i);  /* key (table is in 'ra') */
         TValue *rc = RKC(i);  /* value */
         lua_Unsigned n;
         if (ttisinteger(rb)  /* fast track for integers? */
-            ? (n = ivalue(rb), luaV_fastgeti(L, ra, n, slot))
-            : luaV_fastget(L, ra, rb, slot, luaH_get)) {
-          luaV_finishfastset(L, ra, slot, rc);
+            ? (n = ivalue(rb), luaV_fastgeti(L, s2v(ra), n, slot))
+            : luaV_fastget(L, s2v(ra), rb, slot, luaH_get)) {
+          luaV_finishfastset(L, s2v(ra), slot, rc);
         }
         else
-          Protect(luaV_finishset(L, ra, rb, rc, slot));
+          Protect(luaV_finishset(L, s2v(ra), rb, rc, slot));
         vmbreak;
       }
       vmcase(OP_SETI) {
         const TValue *slot;
         int c = GETARG_B(i);
         TValue *rc = RKC(i);
-        if (luaV_fastgeti(L, ra, c, slot)) {
-          luaV_finishfastset(L, ra, slot, rc);
+        if (luaV_fastgeti(L, s2v(ra), c, slot)) {
+          luaV_finishfastset(L, s2v(ra), slot, rc);
         }
         else {
           TValue key;
           setivalue(&key, c);
-          Protect(luaV_finishset(L, ra, &key, rc, slot));
+          Protect(luaV_finishset(L, s2v(ra), &key, rc, slot));
         }
         vmbreak;
       }
@@ -956,11 +959,11 @@ void luaV_execute (lua_State *L) {
         TValue *rb = KB(i);
         TValue *rc = RKC(i);
         TString *key = tsvalue(rb);  /* key must be a string */
-        if (luaV_fastget(L, ra, key, slot, luaH_getshortstr)) {
-          luaV_finishfastset(L, ra, slot, rc);
+        if (luaV_fastget(L, s2v(ra), key, slot, luaH_getshortstr)) {
+          luaV_finishfastset(L, s2v(ra), slot, rc);
         }
         else
-          Protect(luaV_finishset(L, ra, rb, rc, slot));
+          Protect(luaV_finishset(L, s2v(ra), rb, rc, slot));
         vmbreak;
       }
       vmcase(OP_NEWTABLE) {
@@ -969,7 +972,7 @@ void luaV_execute (lua_State *L) {
         Table *t;
         savepc(L);  /* in case of allocation errors */
         t = luaH_new(L);
-        sethvalue(L, ra, t);
+        sethvalue2s(L, ra, t);
         if (b != 0 || c != 0)
           luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c));
         checkGC(L, ra + 1);
@@ -977,10 +980,10 @@ void luaV_execute (lua_State *L) {
       }
       vmcase(OP_SELF) {
         const TValue *slot;
-        StkId rb = RB(i);
+        TValue *rb = vRB(i);
         TValue *rc = RKC(i);
         TString *key = tsvalue(rc);  /* key must be a string */
-        setobjs2s(L, ra + 1, rb);
+        setobj2s(L, ra + 1, rb);
         if (luaV_fastget(L, rb, key, slot, luaH_getstr)) {
           setobj2s(L, ra, slot);
         }
@@ -988,14 +991,14 @@ void luaV_execute (lua_State *L) {
         vmbreak;
       }
       vmcase(OP_ADDI) {
-        TValue *rb = RB(i);
+        TValue *rb = vRB(i);
         int ic = GETARG_C(i);
         lua_Number nb;
         if (ttisinteger(rb)) {
-          setivalue(ra, intop(+, ivalue(rb), ic));
+          setivalue(s2v(ra), intop(+, ivalue(rb), ic));
         }
         else if (tonumber(rb, &nb)) {
-          setfltvalue(ra, luai_numadd(L, nb, cast_num(ic)));
+          setfltvalue(s2v(ra), luai_numadd(L, nb, cast_num(ic)));
         }
         else {
           TValue aux; TValue *rc;
@@ -1014,10 +1017,10 @@ void luaV_execute (lua_State *L) {
         lua_Number nb; lua_Number nc;
         if (ttisinteger(rb) && ttisinteger(rc)) {
           lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc);
-          setivalue(ra, intop(+, ib, ic));
+          setivalue(s2v(ra), intop(+, ib, ic));
         }
         else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
-          setfltvalue(ra, luai_numadd(L, nb, nc));
+          setfltvalue(s2v(ra), luai_numadd(L, nb, nc));
         }
         else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_ADD)); }
         vmbreak;
@@ -1028,10 +1031,10 @@ void luaV_execute (lua_State *L) {
         lua_Number nb; lua_Number nc;
         if (ttisinteger(rb) && ttisinteger(rc)) {
           lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc);
-          setivalue(ra, intop(-, ib, ic));
+          setivalue(s2v(ra), intop(-, ib, ic));
         }
         else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
-          setfltvalue(ra, luai_numsub(L, nb, nc));
+          setfltvalue(s2v(ra), luai_numsub(L, nb, nc));
         }
         else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SUB)); }
         vmbreak;
@@ -1042,10 +1045,10 @@ void luaV_execute (lua_State *L) {
         lua_Number nb; lua_Number nc;
         if (ttisinteger(rb) && ttisinteger(rc)) {
           lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc);
-          setivalue(ra, intop(*, ib, ic));
+          setivalue(s2v(ra), intop(*, ib, ic));
         }
         else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
-          setfltvalue(ra, luai_nummul(L, nb, nc));
+          setfltvalue(s2v(ra), luai_nummul(L, nb, nc));
         }
         else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_MUL)); }
         vmbreak;
@@ -1055,7 +1058,7 @@ void luaV_execute (lua_State *L) {
         TValue *rc = RKC(i);
         lua_Number nb; lua_Number nc;
         if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
-          setfltvalue(ra, luai_numdiv(L, nb, nc));
+          setfltvalue(s2v(ra), luai_numdiv(L, nb, nc));
         }
         else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_DIV)); }
         vmbreak;
@@ -1065,7 +1068,7 @@ void luaV_execute (lua_State *L) {
         TValue *rc = RKC(i);
         lua_Integer ib; lua_Integer ic;
         if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
-          setivalue(ra, intop(&, ib, ic));
+          setivalue(s2v(ra), intop(&, ib, ic));
         }
         else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BAND)); }
         vmbreak;
@@ -1075,7 +1078,7 @@ void luaV_execute (lua_State *L) {
         TValue *rc = RKC(i);
         lua_Integer ib; lua_Integer ic;
         if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
-          setivalue(ra, intop(|, ib, ic));
+          setivalue(s2v(ra), intop(|, ib, ic));
         }
         else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BOR)); }
         vmbreak;
@@ -1085,7 +1088,7 @@ void luaV_execute (lua_State *L) {
         TValue *rc = RKC(i);
         lua_Integer ib; lua_Integer ic;
         if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
-          setivalue(ra, intop(^, ib, ic));
+          setivalue(s2v(ra), intop(^, ib, ic));
         }
         else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BXOR)); }
         vmbreak;
@@ -1095,7 +1098,7 @@ void luaV_execute (lua_State *L) {
         TValue *rc = RKC(i);
         lua_Integer ib; lua_Integer ic;
         if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
-          setivalue(ra, luaV_shiftl(ib, ic));
+          setivalue(s2v(ra), luaV_shiftl(ib, ic));
         }
         else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHL)); }
         vmbreak;
@@ -1105,7 +1108,7 @@ void luaV_execute (lua_State *L) {
         TValue *rc = RKC(i);
         lua_Integer ib; lua_Integer ic;
         if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
-          setivalue(ra, luaV_shiftl(ib, -ic));
+          setivalue(s2v(ra), luaV_shiftl(ib, -ic));
         }
         else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHR)); }
         vmbreak;
@@ -1116,12 +1119,12 @@ void luaV_execute (lua_State *L) {
         lua_Number nb; lua_Number nc;
         if (ttisinteger(rb) && ttisinteger(rc)) {
           lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc);
-          setivalue(ra, luaV_mod(L, ib, ic));
+          setivalue(s2v(ra), luaV_mod(L, ib, ic));
         }
         else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
           lua_Number m;
           luai_nummod(L, nb, nc, m);
-          setfltvalue(ra, m);
+          setfltvalue(s2v(ra), m);
         }
         else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_MOD)); }
         vmbreak;
@@ -1132,10 +1135,10 @@ void luaV_execute (lua_State *L) {
         lua_Number nb; lua_Number nc;
         if (ttisinteger(rb) && ttisinteger(rc)) {
           lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc);
-          setivalue(ra, luaV_div(L, ib, ic));
+          setivalue(s2v(ra), luaV_div(L, ib, ic));
         }
         else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
-          setfltvalue(ra, luai_numidiv(L, nb, nc));
+          setfltvalue(s2v(ra), luai_numidiv(L, nb, nc));
         }
         else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_IDIV)); }
         vmbreak;
@@ -1145,20 +1148,20 @@ void luaV_execute (lua_State *L) {
         TValue *rc = RKC(i);
         lua_Number nb; lua_Number nc;
         if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
-          setfltvalue(ra, luai_numpow(L, nb, nc));
+          setfltvalue(s2v(ra), luai_numpow(L, nb, nc));
         }
         else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_POW)); }
         vmbreak;
       }
       vmcase(OP_UNM) {
-        TValue *rb = RB(i);
+        TValue *rb = vRB(i);
         lua_Number nb;
         if (ttisinteger(rb)) {
           lua_Integer ib = ivalue(rb);
-          setivalue(ra, intop(-, 0, ib));
+          setivalue(s2v(ra), intop(-, 0, ib));
         }
         else if (tonumber(rb, &nb)) {
-          setfltvalue(ra, luai_numunm(L, nb));
+          setfltvalue(s2v(ra), luai_numunm(L, nb));
         }
         else {
           Protect(luaT_trybinTM(L, rb, rb, ra, TM_UNM));
@@ -1166,10 +1169,10 @@ void luaV_execute (lua_State *L) {
         vmbreak;
       }
       vmcase(OP_BNOT) {
-        TValue *rb = RB(i);
+        TValue *rb = vRB(i);
         lua_Integer ib;
         if (tointeger(rb, &ib)) {
-          setivalue(ra, intop(^, ~l_castS2U(0), ib));
+          setivalue(s2v(ra), intop(^, ~l_castS2U(0), ib));
         }
         else {
           Protect(luaT_trybinTM(L, rb, rb, ra, TM_BNOT));
@@ -1177,13 +1180,13 @@ void luaV_execute (lua_State *L) {
         vmbreak;
       }
       vmcase(OP_NOT) {
-        TValue *rb = RB(i);
+        TValue *rb = vRB(i);
         int res = l_isfalse(rb);  /* next assignment may change this value */
-        setbvalue(ra, res);
+        setbvalue(s2v(ra), res);
         vmbreak;
       }
       vmcase(OP_LEN) {
-        Protect(luaV_objlen(L, ra, RB(i)));
+        Protect(luaV_objlen(L, ra, vRB(i)));
         vmbreak;
       }
       vmcase(OP_CONCAT) {
@@ -1245,18 +1248,18 @@ void luaV_execute (lua_State *L) {
         vmbreak;
       }
       vmcase(OP_TEST) {
-        if (GETARG_C(i) ? l_isfalse(ra) : !l_isfalse(ra))
+        if (GETARG_C(i) ? l_isfalse(s2v(ra)) : !l_isfalse(s2v(ra)))
             pc++;
           else
           donextjump(ci);
         vmbreak;
       }
       vmcase(OP_TESTSET) {
-        TValue *rb = RB(i);
+        TValue *rb = vRB(i);
         if (GETARG_C(i) ? l_isfalse(rb) : !l_isfalse(rb))
           pc++;
         else {
-          setobjs2s(L, ra, rb);
+          setobj2s(L, ra, rb);
           donextjump(ci);
         }
         vmbreak;
@@ -1295,7 +1298,7 @@ void luaV_execute (lua_State *L) {
           StkId nfunc = nci->func;  /* called function */
           StkId ofunc = oci->func;  /* caller function */
           /* last stack slot filled by 'precall' */
-          StkId lim = nci->func + 1 + getproto(nfunc)->numparams;
+          StkId lim = nci->func + 1 + getproto(s2v(nfunc))->numparams;
           int aux;
           /* close all upvalues from previous call */
           if (cl->p->sizep > 0) luaF_close(L, oci->func + 1);
@@ -1306,7 +1309,8 @@ void luaV_execute (lua_State *L) {
           oci->u.l.savedpc = nci->u.l.savedpc;
           oci->callstatus |= CIST_TAIL;  /* function was tail called */
           ci = L->ci = oci;  /* remove new frame */
-          lua_assert(L->top == oci->func + 1 + getproto(ofunc)->maxstacksize);
+          lua_assert(L->top ==
+                     oci->func + 1 + getproto(s2v(ofunc))->maxstacksize);
           goto newframe;  /* restart luaV_execute over new Lua function */
         }
         vmbreak;
@@ -1327,34 +1331,35 @@ void luaV_execute (lua_State *L) {
         }
       }
       vmcase(OP_FORLOOP) {
-        if (ttisinteger(ra)) {  /* integer loop? */
-          lua_Integer step = ivalue(ra + 2);
-          lua_Integer idx = intop(+, ivalue(ra), step); /* increment index */
-          lua_Integer limit = ivalue(ra + 1);
+        if (ttisinteger(s2v(ra))) {  /* integer loop? */
+          lua_Integer step = ivalue(s2v(ra + 2));
+          lua_Integer idx = intop(+, ivalue(s2v(ra)), step); /* increment index */
+          lua_Integer limit = ivalue(s2v(ra + 1));
           if ((0 < step) ? (idx <= limit) : (limit <= idx)) {
             pc += GETARG_sBx(i);  /* jump back */
-            chgivalue(ra, idx);  /* update internal index... */
-            setivalue(ra + 3, idx);  /* ...and external index */
+            chgivalue(s2v(ra), idx);  /* update internal index... */
+            setivalue(s2v(ra + 3), idx);  /* ...and external index */
           }
         }
         else {  /* floating loop */
-          lua_Number step = fltvalue(ra + 2);
-          lua_Number idx = luai_numadd(L, fltvalue(ra), step); /* inc. index */
-          lua_Number limit = fltvalue(ra + 1);
+          lua_Number step = fltvalue(s2v(ra + 2));
+          lua_Number limit = fltvalue(s2v(ra + 1));
+          lua_Number idx = fltvalue(s2v(ra));
+          idx = luai_numadd(L, idx, step);  /* inc. index */
           if (luai_numlt(0, step) ? luai_numle(idx, limit)
                                   : luai_numle(limit, idx)) {
             pc += GETARG_sBx(i);  /* jump back */
-            chgfltvalue(ra, idx);  /* update internal index... */
-            setfltvalue(ra + 3, idx);  /* ...and external index */
+            chgfltvalue(s2v(ra), idx);  /* update internal index... */
+            setfltvalue(s2v(ra + 3), idx);  /* ...and external index */
           }
         }
         updatemask(L);
         vmbreak;
       }
       vmcase(OP_FORPREP) {
-        TValue *init = ra;
-        TValue *plimit = ra + 1;
-        TValue *pstep = ra + 2;
+        TValue *init = s2v(ra);
+        TValue *plimit = s2v(ra + 1);
+        TValue *pstep = s2v(ra + 2);
         lua_Integer ilimit;
         int stopnow;
         if (ttisinteger(init) && ttisinteger(pstep) &&
@@ -1395,7 +1400,7 @@ void luaV_execute (lua_State *L) {
       }
       vmcase(OP_TFORLOOP) {
         l_tforloop:
-        if (!ttisnil(ra + 1)) {  /* continue loop? */
+        if (!ttisnil(s2v(ra + 1))) {  /* continue loop? */
           setobjs2s(L, ra, ra + 1);  /* save control variable */
           pc += GETARG_sBx(i);  /* jump back */
         }
@@ -1411,13 +1416,13 @@ void luaV_execute (lua_State *L) {
           lua_assert(GET_OPCODE(*pc) == OP_EXTRAARG);
           c = GETARG_Ax(*pc++);
         }
-        h = hvalue(ra);
+        h = hvalue(s2v(ra));
         last = ((c-1)*LFIELDS_PER_FLUSH) + n;
         savepc(L);  /* in case of allocation errors */
         if (last > h->sizearray)  /* needs more space? */
           luaH_resizearray(L, h, last);  /* preallocate it at once */
         for (; n > 0; n--) {
-          TValue *val = ra + n;
+          TValue *val = s2v(ra + n);
           setobj2t(L, &h->array[last - 1], val);
           last--;
           luaC_barrierback(L, h, val);
@@ -1433,13 +1438,13 @@ void luaV_execute (lua_State *L) {
           pushclosure(L, p, cl->upvals, base, ra);  /* create a new one */
         }
         else
-          setclLvalue(L, ra, ncl);  /* push cashed closure */
+          setclLvalue2s(L, ra, ncl);  /* push cashed closure */
         checkGC(L, ra + 1);
         vmbreak;
       }
       vmcase(OP_VARARG) {
         int b = GETARG_B(i) - 1;  /* required results */
-        StkId vtab = base + cl->p->numparams - 1;  /* vararg table */
+        TValue *vtab = s2v(base + cl->p->numparams - 1);  /* vararg table */
         Protect(luaT_getvarargs(L, vtab, ra, b));
         vmbreak;
       }

+ 2 - 2
lvm.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.h,v 2.43 2017/06/01 20:23:27 roberto Exp roberto $
+** $Id: lvm.h,v 2.44 2017/06/09 19:16:41 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -93,7 +93,7 @@ LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode);
 LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key,
                                StkId val, const TValue *slot);
 LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
-                               StkId val, const TValue *slot);
+                               TValue *val, const TValue *slot);
 LUAI_FUNC void luaV_finishOp (lua_State *L);
 LUAI_FUNC void luaV_execute (lua_State *L);
 LUAI_FUNC void luaV_concat (lua_State *L, int total);