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

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

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

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

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
** See Copyright Notice in lua.h
*/
@ -30,7 +30,7 @@
#define savestack(L,p) ((char *)(p) - (char *)L->stack)
#define restorestack(L,n) ((TValue *)((char *)L->stack + (n)))
#define restorestack(L,n) ((StkId)((char *)L->stack + (n)))
/* macro to check stack size, preserving 'p' */

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

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

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

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

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

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

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

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

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

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
** See Copyright Notice in lua.h
*/
@ -46,7 +46,7 @@ void *l_Trick = 0;
int islocked = 0;
#define obj_at(L,k) (L->ci->func + (k))
#define obj_at(L,k) s2v(L->ci->func + (k))
static int runC (lua_State *L, lua_State *L1, const char *pc);
@ -316,7 +316,7 @@ static int lua_checkpc (lua_State *L, CallInfo *ci) {
StkId f = (L->status != LUA_YIELD || ci != L->ci)
? ci->func
: restorestack(L, ci->extra);
Proto *p = clLvalue(f)->p;
Proto *p = clLvalue(s2v(f))->p;
return p->code <= ci->u.l.savedpc &&
ci->u.l.savedpc <= p->code + p->sizecode;
}
@ -336,7 +336,7 @@ static void checkstack (global_State *g, lua_State *L1) {
}
if (L1->stack) { /* complete thread? */
for (o = L1->stack; o < L1->stack_last + EXTRA_STACK; o++)
checkliveness(L1, o); /* entire stack must have valid values */
checkliveness(L1, s2v(o)); /* entire stack must have valid values */
}
else lua_assert(L1->stacksize == 0);
}

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

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
** See Copyright Notice in lua.h
*/
@ -63,14 +63,16 @@ LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o,
LUAI_FUNC void luaT_init (lua_State *L);
LUAI_FUNC void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
const TValue *p2, TValue *p3, int hasres);
const TValue *p2, const TValue *p3);
LUAI_FUNC void luaT_callTMres (lua_State *L, const TValue *f,
const TValue *p1, const TValue *p2, StkId p3);
LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
StkId res, TMS event);
LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1,
const TValue *p2, TMS event);
LUAI_FUNC void luaT_adjustvarargs (lua_State *L, Proto *p, int actual);
LUAI_FUNC void luaT_getvarargs (lua_State *L, StkId t, StkId where,
LUAI_FUNC void luaT_getvarargs (lua_State *L, TValue *t, StkId where,
int wanted);

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

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

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
** See Copyright Notice in lua.h
*/
@ -93,7 +93,7 @@ LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode);
LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key,
StkId val, const TValue *slot);
LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
StkId val, const TValue *slot);
TValue *val, const TValue *slot);
LUAI_FUNC void luaV_finishOp (lua_State *L);
LUAI_FUNC void luaV_execute (lua_State *L);
LUAI_FUNC void luaV_concat (lua_State *L, int total);