new type 'StackValue' for stack elements

(we may want to put extra info there in the future)
This commit is contained in:
Roberto Ierusalimschy 2017-06-29 12:06:44 -03:00
parent 5a1c8d8ef3
commit f96497397a
20 changed files with 409 additions and 351 deletions

268
lapi.c
View File

@ -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 ** Lua API
** See Copyright Notice in lua.h ** 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") 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; CallInfo *ci = L->ci;
if (idx > 0) { if (idx > 0) {
TValue *o = ci->func + idx; StkId o = ci->func + idx;
api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index"); api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index");
if (o >= L->top) return NONVALIDVALUE; if (o >= L->top) return NONVALIDVALUE;
else return o; else return s2v(o);
} }
else if (!ispseudo(idx)) { /* negative index */ else if (!ispseudo(idx)) { /* negative index */
api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid 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) else if (idx == LUA_REGISTRYINDEX)
return &G(L)->l_registry; return &G(L)->l_registry;
else { /* upvalues */ else { /* upvalues */
idx = LUA_REGISTRYINDEX - idx; idx = LUA_REGISTRYINDEX - idx;
api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large"); 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 */ return NONVALIDVALUE; /* it has no upvalues */
else { else {
CClosure *func = clCvalue(ci->func); CClosure *func = clCvalue(s2v(ci->func));
return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : NONVALIDVALUE; 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 ** to be called by 'lua_checkstack' in protected mode, to grow stack
** capturing memory errors ** 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"); api_check(from, to->ci->top - to->top >= n, "stack overflow");
from->top -= n; from->top -= n;
for (i = 0; i < n; i++) { 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' */ to->top++; /* stack already checked by previous 'api_check' */
} }
lua_unlock(to); lua_unlock(to);
@ -175,7 +190,7 @@ LUA_API void lua_settop (lua_State *L, int idx) {
if (idx >= 0) { if (idx >= 0) {
api_check(L, idx <= L->stack_last - (func + 1), "new top too large"); api_check(L, idx <= L->stack_last - (func + 1), "new top too large");
while (L->top < (func + 1) + idx) while (L->top < (func + 1) + idx)
setnilvalue(L->top++); setnilvalue(s2v(L->top++));
L->top = (func + 1) + idx; L->top = (func + 1) + idx;
} }
else { else {
@ -189,11 +204,13 @@ LUA_API void lua_settop (lua_State *L, int idx) {
/* /*
** Reverse the stack segment from 'from' to 'to' ** Reverse the stack segment from 'from' to 'to'
** (auxiliary to 'lua_rotate') ** (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) { static void reverse (lua_State *L, StkId from, StkId to) {
for (; from < to; from++, to--) { for (; from < to; from++, to--) {
TValue temp; TValue temp;
setobj(L, &temp, from); setobj(L, &temp, s2v(from));
setobjs2s(L, from, to); setobjs2s(L, from, to);
setobj2s(L, to, &temp); setobj2s(L, to, &temp);
} }
@ -208,8 +225,7 @@ LUA_API void lua_rotate (lua_State *L, int idx, int n) {
StkId p, t, m; StkId p, t, m;
lua_lock(L); lua_lock(L);
t = L->top - 1; /* end of stack segment being rotated */ t = L->top - 1; /* end of stack segment being rotated */
p = index2addr(L, idx); /* start of segment */ p = index2stack(L, idx); /* start of segment */
api_checkstackindex(L, idx, p);
api_check(L, (n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'"); api_check(L, (n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'");
m = (n >= 0 ? t - n : p - n - 1); /* end of prefix */ m = (n >= 0 ? t - n : p - n - 1); /* end of prefix */
reverse(L, p, m); /* reverse the prefix with length 'n' */ 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) { LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
TValue *fr, *to; TValue *fr, *to;
lua_lock(L); lua_lock(L);
fr = index2addr(L, fromidx); fr = index2value(L, fromidx);
to = index2addr(L, toidx); to = index2value(L, toidx);
api_checkvalidindex(L, to); api_checkvalidindex(L, to);
setobj(L, to, fr); setobj(L, to, fr);
if (isupvalue(toidx)) /* function upvalue? */ 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 /* LUA_REGISTRYINDEX does not need gc barrier
(collector revisits it before finishing collection) */ (collector revisits it before finishing collection) */
lua_unlock(L); 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_API void lua_pushvalue (lua_State *L, int idx) {
lua_lock(L); lua_lock(L);
setobj2s(L, L->top, index2addr(L, idx)); setobj2s(L, L->top, index2value(L, idx));
api_incr_top(L); api_incr_top(L);
lua_unlock(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) { 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); 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) { 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))); return (ttislcf(o) || (ttisCclosure(o)));
} }
LUA_API int lua_isinteger (lua_State *L, int idx) { LUA_API int lua_isinteger (lua_State *L, int idx) {
StkId o = index2addr(L, idx); const TValue *o = index2value(L, idx);
return ttisinteger(o); return ttisinteger(o);
} }
LUA_API int lua_isnumber (lua_State *L, int idx) { LUA_API int lua_isnumber (lua_State *L, int idx) {
lua_Number n; lua_Number n;
const TValue *o = index2addr(L, idx); const TValue *o = index2value(L, idx);
return tonumber(o, &n); return tonumber(o, &n);
} }
LUA_API int lua_isstring (lua_State *L, int idx) { 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)); return (ttisstring(o) || cvt2str(o));
} }
LUA_API int lua_isuserdata (lua_State *L, int idx) { 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)); return (ttisfulluserdata(o) || ttislightuserdata(o));
} }
LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
StkId o1 = index2addr(L, index1); const TValue *o1 = index2value(L, index1);
StkId o2 = index2addr(L, index2); const TValue *o2 = index2value(L, index2);
return (isvalid(o1) && isvalid(o2)) ? luaV_rawequalobj(o1, o2) : 0; 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); api_incr_top(L);
} }
/* first operand at top - 2, second at top - 1; result go to top - 2 */ /* 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 */ L->top--; /* remove second operand */
lua_unlock(L); lua_unlock(L);
} }
LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) { 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; int i = 0;
lua_lock(L); /* may call tag method */ lua_lock(L); /* may call tag method */
o1 = index2addr(L, index1); o1 = index2value(L, index1);
o2 = index2addr(L, index2); o2 = index2value(L, index2);
if (isvalid(o1) && isvalid(o2)) { if (isvalid(o1) && isvalid(o2)) {
switch (op) { switch (op) {
case LUA_OPEQ: i = luaV_equalobj(L, o1, o2); break; 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) { 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) if (sz != 0)
api_incr_top(L); api_incr_top(L);
return sz; 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_API lua_Number lua_tonumberx (lua_State *L, int idx, int *pisnum) {
lua_Number n; lua_Number n;
const TValue *o = index2addr(L, idx); const TValue *o = index2value(L, idx);
int isnum = tonumber(o, &n); int isnum = tonumber(o, &n);
if (!isnum) if (!isnum)
n = 0; /* call to 'tonumber' may change 'n' even if it fails */ 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_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *pisnum) {
lua_Integer res; lua_Integer res;
const TValue *o = index2addr(L, idx); const TValue *o = index2value(L, idx);
int isnum = tointeger(o, &res); int isnum = tointeger(o, &res);
if (!isnum) if (!isnum)
res = 0; /* call to 'tointeger' may change 'n' even if it fails */ 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) { 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); return !l_isfalse(o);
} }
LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { 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 (!ttisstring(o)) {
if (!cvt2str(o)) { /* not convertible? */ if (!cvt2str(o)) { /* not convertible? */
if (len != NULL) *len = 0; 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 */ lua_lock(L); /* 'luaO_tostring' may create a new string */
luaO_tostring(L, o); luaO_tostring(L, o);
luaC_checkGC(L); 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); lua_unlock(L);
} }
if (len != NULL) 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) { 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)) { switch (ttype(o)) {
case LUA_TSHRSTR: return tsvalue(o)->shrlen; case LUA_TSHRSTR: return tsvalue(o)->shrlen;
case LUA_TLNGSTR: return tsvalue(o)->u.lnglen; 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) { 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); if (ttislcf(o)) return fvalue(o);
else if (ttisCclosure(o)) else if (ttisCclosure(o))
return clCvalue(o)->f; 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) { LUA_API void *lua_touserdata (lua_State *L, int idx) {
StkId o = index2addr(L, idx); const TValue *o = index2value(L, idx);
switch (ttnov(o)) { switch (ttnov(o)) {
case LUA_TUSERDATA: return getudatamem(uvalue(o)); case LUA_TUSERDATA: return getudatamem(uvalue(o));
case LUA_TLIGHTUSERDATA: return pvalue(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) { 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); return (!ttisthread(o)) ? NULL : thvalue(o);
} }
LUA_API const void *lua_topointer (lua_State *L, int idx) { 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)) { switch (ttype(o)) {
case LUA_TTABLE: return hvalue(o); case LUA_TTABLE: return hvalue(o);
case LUA_TLCL: return clLvalue(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_API void lua_pushnil (lua_State *L) {
lua_lock(L); lua_lock(L);
setnilvalue(L->top); setnilvalue(s2v(L->top));
api_incr_top(L); api_incr_top(L);
lua_unlock(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_API void lua_pushnumber (lua_State *L, lua_Number n) {
lua_lock(L); lua_lock(L);
setfltvalue(L->top, n); setfltvalue(s2v(L->top), n);
api_incr_top(L); api_incr_top(L);
lua_unlock(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_API void lua_pushinteger (lua_State *L, lua_Integer n) {
lua_lock(L); lua_lock(L);
setivalue(L->top, n); setivalue(s2v(L->top), n);
api_incr_top(L); api_incr_top(L);
lua_unlock(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_API const char *lua_pushstring (lua_State *L, const char *s) {
lua_lock(L); lua_lock(L);
if (s == NULL) if (s == NULL)
setnilvalue(L->top); setnilvalue(s2v(L->top));
else { else {
TString *ts; TString *ts;
ts = luaS_new(L, s); 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_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
lua_lock(L); lua_lock(L);
if (n == 0) { if (n == 0) {
setfvalue(L->top, fn); setfvalue(s2v(L->top), fn);
} }
else { else {
CClosure *cl; CClosure *cl;
@ -542,10 +559,10 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
cl->f = fn; cl->f = fn;
L->top -= n; L->top -= n;
while (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 */ /* does not need barrier because closure is white */
} }
setclCvalue(L, L->top, cl); setclCvalue(L, s2v(L->top), cl);
} }
api_incr_top(L); api_incr_top(L);
luaC_checkGC(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_API void lua_pushboolean (lua_State *L, int b) {
lua_lock(L); 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); api_incr_top(L);
lua_unlock(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_API void lua_pushlightuserdata (lua_State *L, void *p) {
lua_lock(L); lua_lock(L);
setpvalue(L->top, p); setpvalue(s2v(L->top), p);
api_incr_top(L); api_incr_top(L);
lua_unlock(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_API int lua_pushthread (lua_State *L) {
lua_lock(L); lua_lock(L);
setthvalue(L, L->top, L); setthvalue(L, s2v(L->top), L);
api_incr_top(L); api_incr_top(L);
lua_unlock(L); lua_unlock(L);
return (G(L)->mainthread == L); return (G(L)->mainthread == L);
@ -594,10 +611,10 @@ static int auxgetstr (lua_State *L, const TValue *t, const char *k) {
else { else {
setsvalue2s(L, L->top, str); setsvalue2s(L, L->top, str);
api_incr_top(L); 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); 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) { LUA_API int lua_gettable (lua_State *L, int idx) {
const TValue *slot; const TValue *slot;
StkId t; TValue *t;
lua_lock(L); lua_lock(L);
t = index2addr(L, idx); t = index2value(L, idx);
if (luaV_fastget(L, t, L->top - 1, slot, luaH_get)) { if (luaV_fastget(L, t, s2v(L->top - 1), slot, luaH_get)) {
setobj2s(L, L->top - 1, slot); setobj2s(L, L->top - 1, slot);
} }
else 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); 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_API int lua_getfield (lua_State *L, int idx, const char *k) {
lua_lock(L); 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) { LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
StkId t; TValue *t;
const TValue *slot; const TValue *slot;
lua_lock(L); lua_lock(L);
t = index2addr(L, idx); t = index2value(L, idx);
if (luaV_fastgeti(L, t, n, slot)) { if (luaV_fastgeti(L, t, n, slot)) {
setobj2s(L, L->top, 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); api_incr_top(L);
lua_unlock(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) { LUA_API int lua_rawget (lua_State *L, int idx) {
StkId t; TValue *t;
lua_lock(L); lua_lock(L);
t = index2addr(L, idx); t = index2value(L, idx);
api_check(L, ttistable(t), "table expected"); 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); 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) { LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) {
StkId t; TValue *t;
lua_lock(L); lua_lock(L);
t = index2addr(L, idx); t = index2value(L, idx);
api_check(L, ttistable(t), "table expected"); api_check(L, ttistable(t), "table expected");
setobj2s(L, L->top, luaH_getint(hvalue(t), n)); setobj2s(L, L->top, luaH_getint(hvalue(t), n));
api_incr_top(L); api_incr_top(L);
lua_unlock(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) { LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
StkId t; TValue *t;
TValue k; TValue k;
lua_lock(L); lua_lock(L);
t = index2addr(L, idx); t = index2value(L, idx);
api_check(L, ttistable(t), "table expected"); api_check(L, ttistable(t), "table expected");
setpvalue(&k, cast(void *, p)); setpvalue(&k, cast(void *, p));
setobj2s(L, L->top, luaH_get(hvalue(t), &k)); setobj2s(L, L->top, luaH_get(hvalue(t), &k));
api_incr_top(L); api_incr_top(L);
lua_unlock(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; Table *t;
lua_lock(L); lua_lock(L);
t = luaH_new(L); t = luaH_new(L);
sethvalue(L, L->top, t); sethvalue2s(L, L->top, t);
api_incr_top(L); api_incr_top(L);
if (narray > 0 || nrec > 0) if (narray > 0 || nrec > 0)
luaH_resize(L, t, narray, nrec); luaH_resize(L, t, narray, nrec);
@ -703,7 +720,7 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
Table *mt; Table *mt;
int res = 0; int res = 0;
lua_lock(L); lua_lock(L);
obj = index2addr(L, objindex); obj = index2value(L, objindex);
switch (ttnov(obj)) { switch (ttnov(obj)) {
case LUA_TTABLE: case LUA_TTABLE:
mt = hvalue(obj)->metatable; mt = hvalue(obj)->metatable;
@ -716,7 +733,7 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
break; break;
} }
if (mt != NULL) { if (mt != NULL) {
sethvalue(L, L->top, mt); sethvalue2s(L, L->top, mt);
api_incr_top(L); api_incr_top(L);
res = 1; 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) { LUA_API int lua_getuservalue (lua_State *L, int idx) {
StkId o; TValue *o;
lua_lock(L); lua_lock(L);
o = index2addr(L, idx); o = index2value(L, idx);
api_check(L, ttisfulluserdata(o), "full userdata expected"); 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); api_incr_top(L);
lua_unlock(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); TString *str = luaS_new(L, k);
api_checknelems(L, 1); api_checknelems(L, 1);
if (luaV_fastget(L, t, str, slot, luaH_getstr)) { 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 */ L->top--; /* pop value */
} }
else { else {
setsvalue2s(L, L->top, str); /* push 'str' (to make it a TValue) */ setsvalue2s(L, L->top, str); /* push 'str' (to make it a TValue) */
api_incr_top(L); 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 */ L->top -= 2; /* pop value and key */
} }
lua_unlock(L); /* lock done by caller */ 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) { LUA_API void lua_settable (lua_State *L, int idx) {
StkId t; TValue *t;
const TValue *slot; const TValue *slot;
lua_lock(L); lua_lock(L);
api_checknelems(L, 2); api_checknelems(L, 2);
t = index2addr(L, idx); t = index2value(L, idx);
if (luaV_fastget(L, t, L->top - 2, slot, luaH_get)) { if (luaV_fastget(L, t, s2v(L->top - 2), slot, luaH_get)) {
luaV_finishfastset(L, t, slot, L->top - 1); luaV_finishfastset(L, t, slot, s2v(L->top - 1));
} }
else 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 */ L->top -= 2; /* pop index and value */
lua_unlock(L); 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_API void lua_setfield (lua_State *L, int idx, const char *k) {
lua_lock(L); /* unlock done in 'auxsetstr' */ 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) { LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
StkId t; TValue *t;
const TValue *slot; const TValue *slot;
lua_lock(L); lua_lock(L);
api_checknelems(L, 1); api_checknelems(L, 1);
t = index2addr(L, idx); t = index2value(L, idx);
if (luaV_fastgeti(L, t, n, slot)) { 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 { else {
TValue aux; TValue aux;
setivalue(&aux, n); 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 */ L->top--; /* pop value */
lua_unlock(L); 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) { LUA_API void lua_rawset (lua_State *L, int idx) {
StkId o; TValue *o;
TValue *slot; TValue *slot;
lua_lock(L); lua_lock(L);
api_checknelems(L, 2); api_checknelems(L, 2);
o = index2addr(L, idx); o = index2value(L, idx);
api_check(L, ttistable(o), "table expected"); api_check(L, ttistable(o), "table expected");
slot = luaH_set(L, hvalue(o), L->top - 2); slot = luaH_set(L, hvalue(o), s2v(L->top - 2));
setobj2t(L, slot, L->top - 1); setobj2t(L, slot, s2v(L->top - 1));
invalidateTMcache(hvalue(o)); invalidateTMcache(hvalue(o));
luaC_barrierback(L, hvalue(o), L->top-1); luaC_barrierback(L, hvalue(o), s2v(L->top - 1));
L->top -= 2; L->top -= 2;
lua_unlock(L); lua_unlock(L);
} }
LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) { LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) {
StkId o; TValue *o;
lua_lock(L); lua_lock(L);
api_checknelems(L, 1); api_checknelems(L, 1);
o = index2addr(L, idx); o = index2value(L, idx);
api_check(L, ttistable(o), "table expected"); api_check(L, ttistable(o), "table expected");
luaH_setint(L, hvalue(o), n, L->top - 1); luaH_setint(L, hvalue(o), n, s2v(L->top - 1));
luaC_barrierback(L, hvalue(o), L->top-1); luaC_barrierback(L, hvalue(o), s2v(L->top - 1));
L->top--; L->top--;
lua_unlock(L); lua_unlock(L);
} }
LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) { LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) {
StkId o; TValue *o;
TValue k, *slot; TValue k, *slot;
lua_lock(L); lua_lock(L);
api_checknelems(L, 1); api_checknelems(L, 1);
o = index2addr(L, idx); o = index2value(L, idx);
api_check(L, ttistable(o), "table expected"); api_check(L, ttistable(o), "table expected");
setpvalue(&k, cast(void *, p)); setpvalue(&k, cast(void *, p));
slot = luaH_set(L, hvalue(o), &k); slot = luaH_set(L, hvalue(o), &k);
setobj2t(L, slot, L->top - 1); setobj2t(L, slot, s2v(L->top - 1));
luaC_barrierback(L, hvalue(o), L->top - 1); luaC_barrierback(L, hvalue(o), s2v(L->top - 1));
L->top--; L->top--;
lua_unlock(L); lua_unlock(L);
} }
@ -860,12 +877,12 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
Table *mt; Table *mt;
lua_lock(L); lua_lock(L);
api_checknelems(L, 1); api_checknelems(L, 1);
obj = index2addr(L, objindex); obj = index2value(L, objindex);
if (ttisnil(L->top - 1)) if (ttisnil(s2v(L->top - 1)))
mt = NULL; mt = NULL;
else { else {
api_check(L, ttistable(L->top - 1), "table expected"); api_check(L, ttistable(s2v(L->top - 1)), "table expected");
mt = hvalue(L->top - 1); mt = hvalue(s2v(L->top - 1));
} }
switch (ttnov(obj)) { switch (ttnov(obj)) {
case LUA_TTABLE: { 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) { LUA_API void lua_setuservalue (lua_State *L, int idx) {
StkId o; TValue *o;
lua_lock(L); lua_lock(L);
api_checknelems(L, 1); api_checknelems(L, 1);
o = index2addr(L, idx); o = index2value(L, idx);
api_check(L, ttisfulluserdata(o), "full userdata expected"); api_check(L, ttisfulluserdata(o), "full userdata expected");
setuservalue(L, uvalue(o), L->top - 1); setuservalue(L, uvalue(o), s2v(L->top - 1));
luaC_barrier(L, gcvalue(o), L->top - 1); luaC_barrier(L, gcvalue(o), s2v(L->top - 1));
L->top--; L->top--;
lua_unlock(L); lua_unlock(L);
} }
@ -971,8 +988,7 @@ LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
if (errfunc == 0) if (errfunc == 0)
func = 0; func = 0;
else { else {
StkId o = index2addr(L, errfunc); StkId o = index2stack(L, errfunc);
api_checkstackindex(L, errfunc, o);
func = savestack(L, o); func = savestack(L, o);
} }
c.func = L->top - (nargs+1); /* function to be called */ 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); luaZ_init(L, &z, reader, data);
status = luaD_protectedparser(L, &z, chunkname, mode); status = luaD_protectedparser(L, &z, chunkname, mode);
if (status == LUA_OK) { /* no errors? */ 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? */ if (f->nupvalues >= 1) { /* does it have an upvalue? */
/* get global table from registry */ /* get global table from registry */
Table *reg = hvalue(&G(L)->l_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; TValue *o;
lua_lock(L); lua_lock(L);
api_checknelems(L, 1); api_checknelems(L, 1);
o = L->top - 1; o = s2v(L->top - 1);
if (isLfunction(o)) if (isLfunction(o))
status = luaU_dump(L, getproto(o), writer, data, strip); status = luaU_dump(L, getproto(o), writer, data, strip);
else else
@ -1154,10 +1170,10 @@ LUA_API int lua_error (lua_State *L) {
LUA_API int lua_next (lua_State *L, int idx) { LUA_API int lua_next (lua_State *L, int idx) {
StkId t; TValue *t;
int more; int more;
lua_lock(L); lua_lock(L);
t = index2addr(L, idx); t = index2value(L, idx);
api_check(L, ttistable(t), "table expected"); api_check(L, ttistable(t), "table expected");
more = luaH_next(L, hvalue(t), L->top - 1); more = luaH_next(L, hvalue(t), L->top - 1);
if (more) { 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) { LUA_API void lua_len (lua_State *L, int idx) {
StkId t; TValue *t;
lua_lock(L); lua_lock(L);
t = index2addr(L, idx); t = index2value(L, idx);
luaV_objlen(L, L->top, t); luaV_objlen(L, L->top, t);
api_incr_top(L); api_incr_top(L);
lua_unlock(L); lua_unlock(L);
@ -1218,7 +1234,7 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
Udata *u; Udata *u;
lua_lock(L); lua_lock(L);
u = luaS_newudata(L, size); u = luaS_newudata(L, size);
setuvalue(L, L->top, u); setuvalue(L, s2v(L->top), u);
api_incr_top(L); api_incr_top(L);
luaC_checkGC(L); luaC_checkGC(L);
lua_unlock(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) { GCObject **owner) {
switch (ttype(fi)) { switch (ttype(fi)) {
case LUA_TCCL: { /* C closure */ 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; const char *name;
TValue *val = NULL; /* to avoid warnings */ TValue *val = NULL; /* to avoid warnings */
lua_lock(L); lua_lock(L);
name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL); name = aux_upvalue(index2value(L, funcindex), n, &val, NULL);
if (name) { if (name) {
setobj2s(L, L->top, val); setobj2s(L, L->top, val);
api_incr_top(L); api_incr_top(L);
@ -1270,14 +1286,14 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
const char *name; const char *name;
TValue *val = NULL; /* to avoid warnings */ TValue *val = NULL; /* to avoid warnings */
GCObject *owner = NULL; /* to avoid warnings */ GCObject *owner = NULL; /* to avoid warnings */
StkId fi; TValue *fi;
lua_lock(L); lua_lock(L);
fi = index2addr(L, funcindex); fi = index2value(L, funcindex);
api_checknelems(L, 1); api_checknelems(L, 1);
name = aux_upvalue(fi, n, &val, &owner); name = aux_upvalue(fi, n, &val, &owner);
if (name) { if (name) {
L->top--; L->top--;
setobj(L, val, L->top); setobj(L, val, s2v(L->top));
luaC_barrier(L, owner, val); luaC_barrier(L, owner, val);
} }
lua_unlock(L); 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) { static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
LClosure *f; LClosure *f;
StkId fi = index2addr(L, fidx); TValue *fi = index2value(L, fidx);
api_check(L, ttisLclosure(fi), "Lua function expected"); api_check(L, ttisLclosure(fi), "Lua function expected");
f = clLvalue(fi); f = clLvalue(fi);
api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index"); 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) { 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)) { switch (ttype(fi)) {
case LUA_TLCL: { /* lua closure */ case LUA_TLCL: { /* lua closure */
return *getupvalref(L, fidx, n, NULL); return *getupvalref(L, fidx, n, NULL);

View File

@ -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 ** Code generator for Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -1079,7 +1079,7 @@ static int constfolding (FuncState *fs, int op, expdesc *e1,
TValue v1, v2, res; TValue v1, v2, res;
if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2)) if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2))
return 0; /* non-numeric operands or not safe to fold */ 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)) { if (ttisinteger(&res)) {
e1->k = VKINT; e1->k = VKINT;
e1->u.ival = ivalue(&res); e1->u.ival = ivalue(&res);

View File

@ -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 ** Debug Interface
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -35,7 +35,7 @@
/* Active Lua function (given call info) */ /* 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, 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); lua_lock(L);
swapextra(L); swapextra(L);
if (ar == NULL) { /* information about non-active function? */ 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; name = NULL;
else /* consider live variables at function start (parameters) */ 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' */ else { /* active function; get information through 'ar' */
StkId pos = NULL; /* to avoid warnings */ StkId pos = NULL; /* to avoid warnings */
name = findlocal(L, ar->i_ci, n, &pos); name = findlocal(L, ar->i_ci, n, &pos);
if (name) { if (name) {
setobj2s(L, L->top, pos); setobjs2s(L, L->top, pos);
api_incr_top(L); 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) { static void collectvalidlines (lua_State *L, Closure *f) {
if (noLuaClosure(f)) { if (noLuaClosure(f)) {
setnilvalue(L->top); setnilvalue(s2v(L->top));
api_incr_top(L); api_incr_top(L);
} }
else { else {
@ -283,7 +283,7 @@ static void collectvalidlines (lua_State *L, Closure *f) {
Proto *p = f->l.p; Proto *p = f->l.p;
int currentline = p->linedefined; int currentline = p->linedefined;
Table *t = luaH_new(L); /* new table to store active lines */ 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); api_incr_top(L);
setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */ setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */
for (i = 0; i < p->sizelineinfo; i++) { /* for all lines with code */ 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; int status;
Closure *cl; Closure *cl;
CallInfo *ci; CallInfo *ci;
StkId func; TValue *func;
lua_lock(L); lua_lock(L);
swapextra(L); swapextra(L);
if (*what == '>') { if (*what == '>') {
ci = NULL; ci = NULL;
func = L->top - 1; func = s2v(L->top - 1);
api_check(L, ttisfunction(func), "function expected"); api_check(L, ttisfunction(func), "function expected");
what++; /* skip the '>' */ what++; /* skip the '>' */
L->top--; /* pop function */ L->top--; /* pop function */
} }
else { else {
ci = ar->i_ci; ci = ar->i_ci;
func = ci->func; func = s2v(ci->func);
lua_assert(ttisfunction(ci->func)); lua_assert(ttisfunction(func));
} }
cl = ttisclosure(func) ? clvalue(func) : NULL; cl = ttisclosure(func) ? clvalue(func) : NULL;
status = auxgetinfo(L, what, ar, cl, ci); status = auxgetinfo(L, what, ar, cl, ci);
if (strchr(what, 'f')) { if (strchr(what, 'f')) {
setobjs2s(L, L->top, func); setobj2s(L, L->top, func);
api_incr_top(L); api_incr_top(L);
} }
swapextra(L); /* correct before option 'L', which can raise a mem. error */ 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) { static int isinstack (CallInfo *ci, const TValue *o) {
StkId base = ci->func + 1; StkId base = ci->func + 1;
ptrdiff_t i = o - base; ptrdiff_t i = cast(StkId, o) - base;
return (0 <= i && i < (ci->top - base) && base + i == o); 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 */ kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */
if (!kind && isinstack(ci, o)) /* no? try a register */ if (!kind && isinstack(ci, o)) /* no? try a register */
kind = getobjname(ci_func(ci)->p, currentpc(ci), 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) : ""; return (kind) ? luaO_pushfstring(L, " (%s '%s')", kind, name) : "";
} }

38
ldo.c
View File

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

4
ldo.h
View File

@ -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 ** Stack and Call structure of Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -30,7 +30,7 @@
#define savestack(L,p) ((char *)(p) - (char *)L->stack) #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' */ /* macro to check stack size, preserving 'p' */

12
lfunc.c
View File

@ -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 ** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -61,9 +61,8 @@ UpVal *luaF_findupval (lua_State *L, StkId level) {
UpVal *p; UpVal *p;
UpVal *uv; UpVal *uv;
lua_assert(isintwups(L) || L->openupval == NULL); lua_assert(isintwups(L) || L->openupval == NULL);
while ((p = *pp) != NULL && p->v >= level) { while ((p = *pp) != NULL && uplevel(p) >= level) {
lua_assert(upisopen(p)); if (uplevel(p) == level && !isdead(G(L), p)) /* corresponding upvalue? */
if (p->v == level && !isdead(G(L), p)) /* corresponding upvalue? */
return p; /* return it */ return p; /* return it */
pp = &p->u.open.next; pp = &p->u.open.next;
} }
@ -75,7 +74,7 @@ UpVal *luaF_findupval (lua_State *L, StkId level) {
if (p) if (p)
p->u.open.previous = &uv->u.open.next; p->u.open.previous = &uv->u.open.next;
*pp = uv; *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? */ if (!isintwups(L)) { /* thread not in list of threads with upvalues? */
L->twups = G(L)->twups; /* link it to the list */ L->twups = G(L)->twups; /* link it to the list */
G(L)->twups = L; G(L)->twups = L;
@ -94,7 +93,8 @@ void luaF_unlinkupval (UpVal *uv) {
void luaF_close (lua_State *L, StkId level) { void luaF_close (lua_State *L, StkId level) {
UpVal *uv; 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 */ TValue *slot = &uv->u.value; /* new position for value */
luaF_unlinkupval(uv); luaF_unlinkupval(uv);
setobj(L, slot, uv->v); /* move value to upvalue slot */ setobj(L, slot, uv->v); /* move value to upvalue slot */

View File

@ -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 ** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -32,6 +32,9 @@
#define upisopen(up) ((up)->v != &(up)->u.value) #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 ** maximum number of misses before giving up the cache of closures
** in prototypes ** in prototypes

10
lgc.c
View File

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

4
llex.c
View File

@ -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 ** Lexical Analyzer
** See Copyright Notice in lua.h ** 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' */ TValue *o; /* entry for 'str' */
TString *ts = luaS_newlstr(L, str, l); /* create new string */ TString *ts = luaS_newlstr(L, str, l); /* create new string */
setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */ 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? */ if (ttisnil(o)) { /* not in use yet? */
/* boolean value does not need GC barrier; /* boolean value does not need GC barrier;
table is not a metatable, so it does not need to invalidate cache */ table is not a metatable, so it does not need to invalidate cache */

View File

@ -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 ** Some generic functions over Lua objects
** See Copyright Notice in lua.h ** 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, int luaO_rawarith (lua_State *L, int op, const TValue *p1, const TValue *p2,
TValue *res) { TValue *res) {
switch (op) { switch (op) {
case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR: case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR:
case LUA_OPSHL: case LUA_OPSHR: 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; lua_Integer i1; lua_Integer i2;
if (tointeger(p1, &i1) && tointeger(p2, &i2)) { if (tointeger(p1, &i1) && tointeger(p2, &i2)) {
setivalue(res, intarith(L, op, i1, 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 */ case LUA_OPDIV: case LUA_OPPOW: { /* operate only on floats */
lua_Number n1; lua_Number n2; lua_Number n1; lua_Number n2;
if (tonumber(p1, &n1) && tonumber(p2, &n2)) { if (tonumber(p1, &n1) && tonumber(p2, &n2)) {
setfltvalue(res, numarith(L, op, n1, n2)); setfltvalue(res, numarith(L, op, n1, n2));
return; return 1;
} }
else break; /* go to the end */ else return 0; /* fail */
} }
default: { /* other operations */ default: { /* other operations */
lua_Number n1; lua_Number n2; lua_Number n1; lua_Number n2;
if (ttisinteger(p1) && ttisinteger(p2)) { if (ttisinteger(p1) && ttisinteger(p2)) {
setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2))); setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2)));
return; return 1;
} }
else if (tonumber(p1, &n1) && tonumber(p2, &n2)) { else if (tonumber(p1, &n1) && tonumber(p2, &n2)) {
setfltvalue(res, numarith(L, op, n1, 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 ** 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]; char buff[MAXNUMBER2STR];
size_t len; size_t len;
lua_assert(ttisnumber(obj)); lua_assert(ttisnumber(obj));
@ -382,7 +389,7 @@ void luaO_tostring (lua_State *L, StkId obj) {
} }
#endif #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; break;
} }
case 'd': { /* an 'int' */ case 'd': { /* an 'int' */
setivalue(L->top, va_arg(argp, int)); setivalue(s2v(L->top), va_arg(argp, int));
goto top2str; goto top2str;
} }
case 'I': { /* a 'lua_Integer' */ 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; goto top2str;
} }
case 'f': { /* a 'lua_Number' */ 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 */ top2str: /* convert the top element to a string */
luaD_inctop(L); luaD_inctop(L);
luaO_tostring(L, L->top - 1); luaO_tostring(L, s2v(L->top - 1));
break; break;
} }
case 'p': { /* a pointer */ 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); luaD_checkstack(L, 1);
pushstr(L, fmt, strlen(fmt)); pushstr(L, fmt, strlen(fmt));
if (n > 0) luaV_concat(L, n + 1); if (n > 0) luaV_concat(L, n + 1);
return svalue(L->top - 1); return svalue(s2v(L->top - 1));
} }

View File

@ -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 ** Type definitions for Lua objects
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -110,7 +110,7 @@ typedef union Value {
#define TValuefields Value value_; lu_byte tt_ #define TValuefields Value value_; lu_byte tt_
typedef struct lua_TValue { typedef struct TValue {
TValuefields; TValuefields;
} TValue; } TValue;
@ -282,13 +282,15 @@ typedef struct lua_TValue {
** different types of assignments, according to destination ** different types of assignments, according to destination
*/ */
/* from stack to (same) stack */ /* from stack to stack */
#define setobjs2s setobj #define setobjs2s(L,o1,o2) setobj(L,s2v(o1),s2v(o2))
/* to stack (not from same stack) */ /* to stack (not from same stack) */
#define setobj2s setobj #define setobj2s(L,o1,o2) setobj(L,s2v(o1),o2)
#define setsvalue2s setsvalue #define setsvalue2s(L,o,s) setsvalue(L,s2v(o),s)
#define sethvalue2s sethvalue #define sethvalue2s(L,o,h) sethvalue(L,s2v(o),h)
#define setptvalue2s setptvalue #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 */ /* from table to same table */
#define setobjt2t setobj #define setobjt2t setobj
/* to new object */ /* 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_fb2int (int x);
LUAI_FUNC int luaO_utf8esc (char *buff, unsigned long x); LUAI_FUNC int luaO_utf8esc (char *buff, unsigned long x);
LUAI_FUNC int luaO_ceillog2 (unsigned int 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, 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 size_t luaO_str2num (const char *s, TValue *o);
LUAI_FUNC int luaO_hexavalue (int c); 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, LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
va_list argp); va_list argp);
LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);

View File

@ -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 ** Lua Parser
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -1650,10 +1650,10 @@ LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
LexState lexstate; LexState lexstate;
FuncState funcstate; FuncState funcstate;
LClosure *cl = luaF_newLclosure(L, 1); /* create main closure */ 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); luaD_inctop(L);
lexstate.h = luaH_new(L); /* create table for scanner */ 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); luaD_inctop(L);
funcstate.f = cl->p = luaF_newproto(L); funcstate.f = cl->p = luaF_newproto(L);
funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ funcstate.f->source = luaS_new(L, name); /* create and anchor TString */

View File

@ -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 ** Global State
** See Copyright Notice in lua.h ** 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) { static void stack_init (lua_State *L1, lua_State *L) {
int i; CallInfo *ci; int i; CallInfo *ci;
/* initialize stack array */ /* 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; L1->stacksize = BASIC_STACK_SIZE;
for (i = 0; i < BASIC_STACK_SIZE; i++) 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->top = L1->stack;
L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK; L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK;
/* initialize first ci */ /* initialize first ci */
@ -154,7 +154,7 @@ static void stack_init (lua_State *L1, lua_State *L) {
ci->next = ci->previous = NULL; ci->next = ci->previous = NULL;
ci->callstatus = 0; ci->callstatus = 0;
ci->func = L1->top; 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; ci->top = L1->top + LUA_MINSTACK;
L1->ci = ci; L1->ci = ci;
} }
@ -258,7 +258,7 @@ LUA_API lua_State *lua_newthread (lua_State *L) {
L1->next = g->allgc; L1->next = g->allgc;
g->allgc = obj2gco(L1); g->allgc = obj2gco(L1);
/* anchor it on L stack */ /* anchor it on L stack */
setthvalue(L, L->top, L1); setthvalue2s(L, L->top, L1);
api_incr_top(L); api_incr_top(L);
preinit_thread(L1, g); preinit_thread(L1, g);
L1->hookmask = L->hookmask; L1->hookmask = L->hookmask;

View File

@ -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) ** Lua tables (hash)
** See Copyright Notice in lua.h ** 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 ** elements in the array part, then elements in the hash part. The
** beginning of a traversal is signaled by 0. ** 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; unsigned int i;
if (ttisnil(key)) return 0; /* first iteration */ if (ttisnil(key)) return 0; /* first iteration */
i = ttisinteger(key) ? arrayindex(ivalue(key)) : 0; 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) { 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 */ for (; i < t->sizearray; i++) { /* try first array part */
if (!ttisnil(&t->array[i])) { /* a non-nil value? */ if (!ttisnil(&t->array[i])) { /* a non-nil value? */
setivalue(key, i + 1); setivalue(s2v(key), i + 1);
setobj2s(L, key+1, &t->array[i]); setobj2s(L, key + 1, &t->array[i]);
return 1; return 1;
} }
} }
for (i -= t->sizearray; cast_int(i) < sizenode(t); i++) { /* hash part */ for (i -= t->sizearray; cast_int(i) < sizenode(t); i++) { /* hash part */
if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */
Node *n = gnode(t, i); Node *n = gnode(t, i);
getnodekey(L, key, n); getnodekey(L, s2v(key), n);
setobj2s(L, key + 1, gval(n)); setobj2s(L, key + 1, gval(n));
return 1; return 1;
} }

View File

@ -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 ** Internal Module for Debugging of the Lua Implementation
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -46,7 +46,7 @@ void *l_Trick = 0;
int islocked = 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); 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) StkId f = (L->status != LUA_YIELD || ci != L->ci)
? ci->func ? ci->func
: restorestack(L, ci->extra); : restorestack(L, ci->extra);
Proto *p = clLvalue(f)->p; Proto *p = clLvalue(s2v(f))->p;
return p->code <= ci->u.l.savedpc && return p->code <= ci->u.l.savedpc &&
ci->u.l.savedpc <= p->code + p->sizecode; 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? */ if (L1->stack) { /* complete thread? */
for (o = L1->stack; o < L1->stack_last + EXTRA_STACK; o++) 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); else lua_assert(L1->stacksize == 0);
} }

46
ltm.c
View File

@ -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 ** Tag methods
** See Copyright Notice in lua.h ** 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, 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) {
ptrdiff_t result = savestack(L, 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; StkId func = L->top;
setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */ setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */
setobj2s(L, func + 1, p1); /* 1st argument */ setobj2s(L, func + 1, p1); /* 1st argument */
setobj2s(L, func + 2, p2); /* 2nd argument */ setobj2s(L, func + 2, p2); /* 2nd argument */
L->top += 3; 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 */ /* metamethod may yield only when called from Lua code */
if (isLua(L->ci)) if (isLua(L->ci))
luaD_call(L, func, hasres); luaD_call(L, func, 1);
else else
luaD_callnoyield(L, func, hasres); luaD_callnoyield(L, func, 1);
if (hasres) { /* if has result, move it to its place */ res = restorestack(L, result);
p3 = restorestack(L, result); setobjs2s(L, res, --L->top); /* more result to its place */
setobjs2s(L, p3, --L->top);
}
} }
@ -127,7 +139,7 @@ static int callbinTM (lua_State *L, const TValue *p1, const TValue *p2,
if (ttisnil(tm)) if (ttisnil(tm))
tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
if (ttisnil(tm)) return 0; if (ttisnil(tm)) return 0;
luaT_callTM(L, tm, p1, p2, res, 1); luaT_callTMres(L, tm, p1, p2, res);
return 1; 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)) if (!callbinTM(L, p1, p2, L->top, event))
return -1; /* no metamethod */ return -1; /* no metamethod */
else 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 */ int nfixparams = p->numparams - 1; /* number of fixed parameters */
actual -= nfixparams; /* number of extra arguments */ actual -= nfixparams; /* number of extra arguments */
vtab = luaH_new(L); /* create vararg table */ 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 */ L->top++; /* space ensured by caller */
luaH_resize(L, vtab, actual, 1); luaH_resize(L, vtab, actual, 1);
for (i = 0; i < actual; i++) /* put extra arguments into vararg table */ 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' */ setsvalue(L, &nname, luaS_newliteral(L, "n")); /* get field 'n' */
setivalue(luaH_set(L, vtab, &nname), actual); /* store counter there */ setivalue(luaH_set(L, vtab, &nname), actual); /* store counter there */
L->top -= actual; /* remove extra elements from the stack */ 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)) if (!ttistable(t))
luaG_runerror(L, "'vararg' parameter is not a table"); luaG_runerror(L, "'vararg' parameter is not a table");
else { else {

8
ltm.h
View File

@ -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 ** Tag methods
** See Copyright Notice in lua.h ** 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_init (lua_State *L);
LUAI_FUNC void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, 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, LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
StkId res, TMS event); StkId res, TMS event);
LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1, LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1,
const TValue *p2, TMS event); const TValue *p2, TMS event);
LUAI_FUNC void luaT_adjustvarargs (lua_State *L, Proto *p, int actual); 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); int wanted);

View File

@ -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 ** load precompiled Lua chunks
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -283,7 +283,7 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) {
S.Z = Z; S.Z = Z;
checkHeader(&S); checkHeader(&S);
cl = luaF_newLclosure(L, LoadByte(&S)); cl = luaF_newLclosure(L, LoadByte(&S));
setclLvalue(L, L->top, cl); setclLvalue2s(L, L->top, cl);
luaD_inctop(L); luaD_inctop(L);
cl->p = luaF_newproto(L); cl->p = luaF_newproto(L);
LoadFunction(&S, cl->p, NULL); LoadFunction(&S, cl->p, NULL);

209
lvm.c
View File

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

4
lvm.h
View File

@ -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 ** Lua virtual machine
** See Copyright Notice in lua.h ** 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, LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key,
StkId val, const TValue *slot); StkId val, const TValue *slot);
LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key, 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_finishOp (lua_State *L);
LUAI_FUNC void luaV_execute (lua_State *L); LUAI_FUNC void luaV_execute (lua_State *L);
LUAI_FUNC void luaV_concat (lua_State *L, int total); LUAI_FUNC void luaV_concat (lua_State *L, int total);