mirror of
https://github.com/lua/lua
synced 2024-11-25 06:09:36 +03:00
Stack indices changed to union's
That will allow to change pointers to offsets while reallocating the stack.
This commit is contained in:
parent
ba089bcb08
commit
413a393e62
235
lapi.c
235
lapi.c
@ -60,27 +60,28 @@ const char lua_ident[] =
|
|||||||
static TValue *index2value (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) {
|
||||||
StkId o = ci->func + idx;
|
StkId o = ci->func.p + idx;
|
||||||
api_check(L, idx <= L->ci->top - (ci->func + 1), "unacceptable index");
|
api_check(L, idx <= ci->top.p - (ci->func.p + 1), "unacceptable index");
|
||||||
if (o >= L->top) return &G(L)->nilvalue;
|
if (o >= L->top.p) return &G(L)->nilvalue;
|
||||||
else return s2v(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.p - (ci->func.p + 1),
|
||||||
return s2v(L->top + idx);
|
"invalid index");
|
||||||
|
return s2v(L->top.p + 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 (ttisCclosure(s2v(ci->func))) { /* C closure? */
|
if (ttisCclosure(s2v(ci->func.p))) { /* C closure? */
|
||||||
CClosure *func = clCvalue(s2v(ci->func));
|
CClosure *func = clCvalue(s2v(ci->func.p));
|
||||||
return (idx <= func->nupvalues) ? &func->upvalue[idx-1]
|
return (idx <= func->nupvalues) ? &func->upvalue[idx-1]
|
||||||
: &G(L)->nilvalue;
|
: &G(L)->nilvalue;
|
||||||
}
|
}
|
||||||
else { /* light C function or Lua function (through a hook)?) */
|
else { /* light C function or Lua function (through a hook)?) */
|
||||||
api_check(L, ttislcf(s2v(ci->func)), "caller not a C function");
|
api_check(L, ttislcf(s2v(ci->func.p)), "caller not a C function");
|
||||||
return &G(L)->nilvalue; /* no upvalues */
|
return &G(L)->nilvalue; /* no upvalues */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,14 +95,15 @@ static TValue *index2value (lua_State *L, int idx) {
|
|||||||
l_sinline StkId index2stack (lua_State *L, int idx) {
|
l_sinline StkId index2stack (lua_State *L, int idx) {
|
||||||
CallInfo *ci = L->ci;
|
CallInfo *ci = L->ci;
|
||||||
if (idx > 0) {
|
if (idx > 0) {
|
||||||
StkId o = ci->func + idx;
|
StkId o = ci->func.p + idx;
|
||||||
api_check(L, o < L->top, "invalid index");
|
api_check(L, o < L->top.p, "invalid index");
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
else { /* non-positive index */
|
else { /* non-positive index */
|
||||||
api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
|
api_check(L, idx != 0 && -idx <= L->top.p - (ci->func.p + 1),
|
||||||
|
"invalid index");
|
||||||
api_check(L, !ispseudo(idx), "invalid index");
|
api_check(L, !ispseudo(idx), "invalid index");
|
||||||
return L->top + idx;
|
return L->top.p + idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,12 +114,12 @@ LUA_API int lua_checkstack (lua_State *L, int n) {
|
|||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
ci = L->ci;
|
ci = L->ci;
|
||||||
api_check(L, n >= 0, "negative 'n'");
|
api_check(L, n >= 0, "negative 'n'");
|
||||||
if (L->stack_last - L->top > n) /* stack large enough? */
|
if (L->stack_last.p - L->top.p > n) /* stack large enough? */
|
||||||
res = 1; /* yes; check is OK */
|
res = 1; /* yes; check is OK */
|
||||||
else /* need to grow stack */
|
else /* need to grow stack */
|
||||||
res = luaD_growstack(L, n, 0);
|
res = luaD_growstack(L, n, 0);
|
||||||
if (res && ci->top < L->top + n)
|
if (res && ci->top.p < L->top.p + n)
|
||||||
ci->top = L->top + n; /* adjust frame top */
|
ci->top.p = L->top.p + n; /* adjust frame top */
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -129,11 +131,11 @@ LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
|
|||||||
lua_lock(to);
|
lua_lock(to);
|
||||||
api_checknelems(from, n);
|
api_checknelems(from, n);
|
||||||
api_check(from, G(from) == G(to), "moving among independent states");
|
api_check(from, G(from) == G(to), "moving among independent states");
|
||||||
api_check(from, to->ci->top - to->top >= n, "stack overflow");
|
api_check(from, to->ci->top.p - to->top.p >= n, "stack overflow");
|
||||||
from->top -= n;
|
from->top.p -= n;
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
setobjs2s(to, to->top, from->top + i);
|
setobjs2s(to, to->top.p, from->top.p + i);
|
||||||
to->top++; /* stack already checked by previous 'api_check' */
|
to->top.p++; /* stack already checked by previous 'api_check' */
|
||||||
}
|
}
|
||||||
lua_unlock(to);
|
lua_unlock(to);
|
||||||
}
|
}
|
||||||
@ -167,12 +169,12 @@ LUA_API lua_Number lua_version (lua_State *L) {
|
|||||||
LUA_API int lua_absindex (lua_State *L, int idx) {
|
LUA_API int lua_absindex (lua_State *L, int idx) {
|
||||||
return (idx > 0 || ispseudo(idx))
|
return (idx > 0 || ispseudo(idx))
|
||||||
? idx
|
? idx
|
||||||
: cast_int(L->top - L->ci->func) + idx;
|
: cast_int(L->top.p - L->ci->func.p) + idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LUA_API int lua_gettop (lua_State *L) {
|
LUA_API int lua_gettop (lua_State *L) {
|
||||||
return cast_int(L->top - (L->ci->func + 1));
|
return cast_int(L->top.p - (L->ci->func.p + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -182,24 +184,24 @@ LUA_API void lua_settop (lua_State *L, int idx) {
|
|||||||
ptrdiff_t diff; /* difference for new top */
|
ptrdiff_t diff; /* difference for new top */
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
ci = L->ci;
|
ci = L->ci;
|
||||||
func = ci->func;
|
func = ci->func.p;
|
||||||
if (idx >= 0) {
|
if (idx >= 0) {
|
||||||
api_check(L, idx <= ci->top - (func + 1), "new top too large");
|
api_check(L, idx <= ci->top.p - (func + 1), "new top too large");
|
||||||
diff = ((func + 1) + idx) - L->top;
|
diff = ((func + 1) + idx) - L->top.p;
|
||||||
for (; diff > 0; diff--)
|
for (; diff > 0; diff--)
|
||||||
setnilvalue(s2v(L->top++)); /* clear new slots */
|
setnilvalue(s2v(L->top.p++)); /* clear new slots */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top");
|
api_check(L, -(idx+1) <= (L->top.p - (func + 1)), "invalid new top");
|
||||||
diff = idx + 1; /* will "subtract" index (as it is negative) */
|
diff = idx + 1; /* will "subtract" index (as it is negative) */
|
||||||
}
|
}
|
||||||
api_check(L, L->tbclist < L->top, "previous pop of an unclosed slot");
|
api_check(L, L->tbclist.p < L->top.p, "previous pop of an unclosed slot");
|
||||||
newtop = L->top + diff;
|
newtop = L->top.p + diff;
|
||||||
if (diff < 0 && L->tbclist >= newtop) {
|
if (diff < 0 && L->tbclist.p >= newtop) {
|
||||||
lua_assert(hastocloseCfunc(ci->nresults));
|
lua_assert(hastocloseCfunc(ci->nresults));
|
||||||
newtop = luaF_close(L, newtop, CLOSEKTOP, 0);
|
newtop = luaF_close(L, newtop, CLOSEKTOP, 0);
|
||||||
}
|
}
|
||||||
L->top = newtop; /* correct top only after closing any upvalue */
|
L->top.p = newtop; /* correct top only after closing any upvalue */
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,7 +210,7 @@ LUA_API void lua_closeslot (lua_State *L, int idx) {
|
|||||||
StkId level;
|
StkId level;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
level = index2stack(L, idx);
|
level = index2stack(L, idx);
|
||||||
api_check(L, hastocloseCfunc(L->ci->nresults) && L->tbclist == level,
|
api_check(L, hastocloseCfunc(L->ci->nresults) && L->tbclist.p == level,
|
||||||
"no variable to close at given level");
|
"no variable to close at given level");
|
||||||
level = luaF_close(L, level, CLOSEKTOP, 0);
|
level = luaF_close(L, level, CLOSEKTOP, 0);
|
||||||
setnilvalue(s2v(level));
|
setnilvalue(s2v(level));
|
||||||
@ -239,7 +241,7 @@ l_sinline void reverse (lua_State *L, StkId from, StkId to) {
|
|||||||
LUA_API void lua_rotate (lua_State *L, int idx, int n) {
|
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.p - 1; /* end of stack segment being rotated */
|
||||||
p = index2stack(L, idx); /* start of segment */
|
p = index2stack(L, idx); /* start of segment */
|
||||||
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 */
|
||||||
@ -258,7 +260,7 @@ LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
|
|||||||
api_check(L, isvalid(L, to), "invalid index");
|
api_check(L, isvalid(L, to), "invalid index");
|
||||||
setobj(L, to, fr);
|
setobj(L, to, fr);
|
||||||
if (isupvalue(toidx)) /* function upvalue? */
|
if (isupvalue(toidx)) /* function upvalue? */
|
||||||
luaC_barrier(L, clCvalue(s2v(L->ci->func)), fr);
|
luaC_barrier(L, clCvalue(s2v(L->ci->func.p)), 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);
|
||||||
@ -267,7 +269,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, index2value(L, idx));
|
setobj2s(L, L->top.p, index2value(L, idx));
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
@ -336,12 +338,12 @@ LUA_API void lua_arith (lua_State *L, int op) {
|
|||||||
api_checknelems(L, 2); /* all other operations expect two operands */
|
api_checknelems(L, 2); /* all other operations expect two operands */
|
||||||
else { /* for unary operations, add fake 2nd operand */
|
else { /* for unary operations, add fake 2nd operand */
|
||||||
api_checknelems(L, 1);
|
api_checknelems(L, 1);
|
||||||
setobjs2s(L, L->top, L->top - 1);
|
setobjs2s(L, L->top.p, L->top.p - 1);
|
||||||
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, s2v(L->top - 2), s2v(L->top - 1), L->top - 2);
|
luaO_arith(L, op, s2v(L->top.p - 2), s2v(L->top.p - 1), L->top.p - 2);
|
||||||
L->top--; /* remove second operand */
|
L->top.p--; /* remove second operand */
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,7 +369,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, s2v(L->top));
|
size_t sz = luaO_str2num(s, s2v(L->top.p));
|
||||||
if (sz != 0)
|
if (sz != 0)
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
return sz;
|
return sz;
|
||||||
@ -494,7 +496,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(s2v(L->top));
|
setnilvalue(s2v(L->top.p));
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
@ -502,7 +504,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(s2v(L->top), n);
|
setfltvalue(s2v(L->top.p), n);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
@ -510,7 +512,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(s2v(L->top), n);
|
setivalue(s2v(L->top.p), n);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
@ -525,7 +527,7 @@ LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
|
|||||||
TString *ts;
|
TString *ts;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
ts = (len == 0) ? luaS_new(L, "") : luaS_newlstr(L, s, len);
|
ts = (len == 0) ? luaS_new(L, "") : luaS_newlstr(L, s, len);
|
||||||
setsvalue2s(L, L->top, ts);
|
setsvalue2s(L, L->top.p, ts);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
@ -536,11 +538,11 @@ 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(s2v(L->top));
|
setnilvalue(s2v(L->top.p));
|
||||||
else {
|
else {
|
||||||
TString *ts;
|
TString *ts;
|
||||||
ts = luaS_new(L, s);
|
ts = luaS_new(L, s);
|
||||||
setsvalue2s(L, L->top, ts);
|
setsvalue2s(L, L->top.p, ts);
|
||||||
s = getstr(ts); /* internal copy's address */
|
s = getstr(ts); /* internal copy's address */
|
||||||
}
|
}
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
@ -577,7 +579,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(s2v(L->top), fn);
|
setfvalue(s2v(L->top.p), fn);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -586,13 +588,13 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
|
|||||||
api_check(L, n <= MAXUPVAL, "upvalue index too large");
|
api_check(L, n <= MAXUPVAL, "upvalue index too large");
|
||||||
cl = luaF_newCclosure(L, n);
|
cl = luaF_newCclosure(L, n);
|
||||||
cl->f = fn;
|
cl->f = fn;
|
||||||
L->top -= n;
|
L->top.p -= n;
|
||||||
while (n--) {
|
while (n--) {
|
||||||
setobj2n(L, &cl->upvalue[n], s2v(L->top + n));
|
setobj2n(L, &cl->upvalue[n], s2v(L->top.p + n));
|
||||||
/* does not need barrier because closure is white */
|
/* does not need barrier because closure is white */
|
||||||
lua_assert(iswhite(cl));
|
lua_assert(iswhite(cl));
|
||||||
}
|
}
|
||||||
setclCvalue(L, s2v(L->top), cl);
|
setclCvalue(L, s2v(L->top.p), cl);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
}
|
}
|
||||||
@ -603,9 +605,9 @@ 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);
|
||||||
if (b)
|
if (b)
|
||||||
setbtvalue(s2v(L->top));
|
setbtvalue(s2v(L->top.p));
|
||||||
else
|
else
|
||||||
setbfvalue(s2v(L->top));
|
setbfvalue(s2v(L->top.p));
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
@ -613,7 +615,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(s2v(L->top), p);
|
setpvalue(s2v(L->top.p), p);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
@ -621,7 +623,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, s2v(L->top), L);
|
setthvalue(L, s2v(L->top.p), 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);
|
||||||
@ -638,16 +640,16 @@ l_sinline int auxgetstr (lua_State *L, const TValue *t, const char *k) {
|
|||||||
const TValue *slot;
|
const TValue *slot;
|
||||||
TString *str = luaS_new(L, k);
|
TString *str = luaS_new(L, k);
|
||||||
if (luaV_fastget(L, t, str, slot, luaH_getstr)) {
|
if (luaV_fastget(L, t, str, slot, luaH_getstr)) {
|
||||||
setobj2s(L, L->top, slot);
|
setobj2s(L, L->top.p, slot);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
setsvalue2s(L, L->top, str);
|
setsvalue2s(L, L->top.p, str);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
luaV_finishget(L, t, s2v(L->top - 1), L->top - 1, slot);
|
luaV_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, slot);
|
||||||
}
|
}
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return ttype(s2v(L->top - 1));
|
return ttype(s2v(L->top.p - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -674,13 +676,13 @@ LUA_API int lua_gettable (lua_State *L, int idx) {
|
|||||||
TValue *t;
|
TValue *t;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
t = index2value(L, idx);
|
t = index2value(L, idx);
|
||||||
if (luaV_fastget(L, t, s2v(L->top - 1), slot, luaH_get)) {
|
if (luaV_fastget(L, t, s2v(L->top.p - 1), slot, luaH_get)) {
|
||||||
setobj2s(L, L->top - 1, slot);
|
setobj2s(L, L->top.p - 1, slot);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
luaV_finishget(L, t, s2v(L->top - 1), L->top - 1, slot);
|
luaV_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, slot);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return ttype(s2v(L->top - 1));
|
return ttype(s2v(L->top.p - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -696,27 +698,27 @@ LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
|
|||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
t = index2value(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.p, slot);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TValue aux;
|
TValue aux;
|
||||||
setivalue(&aux, n);
|
setivalue(&aux, n);
|
||||||
luaV_finishget(L, t, &aux, L->top, slot);
|
luaV_finishget(L, t, &aux, L->top.p, slot);
|
||||||
}
|
}
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return ttype(s2v(L->top - 1));
|
return ttype(s2v(L->top.p - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
l_sinline int finishrawget (lua_State *L, const TValue *val) {
|
l_sinline int finishrawget (lua_State *L, const TValue *val) {
|
||||||
if (isempty(val)) /* avoid copying empty items to the stack */
|
if (isempty(val)) /* avoid copying empty items to the stack */
|
||||||
setnilvalue(s2v(L->top));
|
setnilvalue(s2v(L->top.p));
|
||||||
else
|
else
|
||||||
setobj2s(L, L->top, val);
|
setobj2s(L, L->top.p, val);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return ttype(s2v(L->top - 1));
|
return ttype(s2v(L->top.p - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -733,8 +735,8 @@ LUA_API int lua_rawget (lua_State *L, int idx) {
|
|||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, 1);
|
api_checknelems(L, 1);
|
||||||
t = gettable(L, idx);
|
t = gettable(L, idx);
|
||||||
val = luaH_get(t, s2v(L->top - 1));
|
val = luaH_get(t, s2v(L->top.p - 1));
|
||||||
L->top--; /* remove key */
|
L->top.p--; /* remove key */
|
||||||
return finishrawget(L, val);
|
return finishrawget(L, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -761,7 +763,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);
|
||||||
sethvalue2s(L, L->top, t);
|
sethvalue2s(L, L->top.p, 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);
|
||||||
@ -788,7 +790,7 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (mt != NULL) {
|
if (mt != NULL) {
|
||||||
sethvalue2s(L, L->top, mt);
|
sethvalue2s(L, L->top.p, mt);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
res = 1;
|
res = 1;
|
||||||
}
|
}
|
||||||
@ -804,12 +806,12 @@ LUA_API int lua_getiuservalue (lua_State *L, int idx, int n) {
|
|||||||
o = index2value(L, idx);
|
o = index2value(L, idx);
|
||||||
api_check(L, ttisfulluserdata(o), "full userdata expected");
|
api_check(L, ttisfulluserdata(o), "full userdata expected");
|
||||||
if (n <= 0 || n > uvalue(o)->nuvalue) {
|
if (n <= 0 || n > uvalue(o)->nuvalue) {
|
||||||
setnilvalue(s2v(L->top));
|
setnilvalue(s2v(L->top.p));
|
||||||
t = LUA_TNONE;
|
t = LUA_TNONE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
setobj2s(L, L->top, &uvalue(o)->uv[n - 1].uv);
|
setobj2s(L, L->top.p, &uvalue(o)->uv[n - 1].uv);
|
||||||
t = ttype(s2v(L->top));
|
t = ttype(s2v(L->top.p));
|
||||||
}
|
}
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
@ -829,14 +831,14 @@ 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, s2v(L->top - 1));
|
luaV_finishfastset(L, t, slot, s2v(L->top.p - 1));
|
||||||
L->top--; /* pop value */
|
L->top.p--; /* pop value */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
setsvalue2s(L, L->top, str); /* push 'str' (to make it a TValue) */
|
setsvalue2s(L, L->top.p, str); /* push 'str' (to make it a TValue) */
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
luaV_finishset(L, t, s2v(L->top - 1), s2v(L->top - 2), slot);
|
luaV_finishset(L, t, s2v(L->top.p - 1), s2v(L->top.p - 2), slot);
|
||||||
L->top -= 2; /* pop value and key */
|
L->top.p -= 2; /* pop value and key */
|
||||||
}
|
}
|
||||||
lua_unlock(L); /* lock done by caller */
|
lua_unlock(L); /* lock done by caller */
|
||||||
}
|
}
|
||||||
@ -856,12 +858,12 @@ LUA_API void lua_settable (lua_State *L, int idx) {
|
|||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, 2);
|
api_checknelems(L, 2);
|
||||||
t = index2value(L, idx);
|
t = index2value(L, idx);
|
||||||
if (luaV_fastget(L, t, s2v(L->top - 2), slot, luaH_get)) {
|
if (luaV_fastget(L, t, s2v(L->top.p - 2), slot, luaH_get)) {
|
||||||
luaV_finishfastset(L, t, slot, s2v(L->top - 1));
|
luaV_finishfastset(L, t, slot, s2v(L->top.p - 1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
luaV_finishset(L, t, s2v(L->top - 2), s2v(L->top - 1), slot);
|
luaV_finishset(L, t, s2v(L->top.p - 2), s2v(L->top.p - 1), slot);
|
||||||
L->top -= 2; /* pop index and value */
|
L->top.p -= 2; /* pop index and value */
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -879,14 +881,14 @@ LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
|
|||||||
api_checknelems(L, 1);
|
api_checknelems(L, 1);
|
||||||
t = index2value(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, s2v(L->top - 1));
|
luaV_finishfastset(L, t, slot, s2v(L->top.p - 1));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TValue aux;
|
TValue aux;
|
||||||
setivalue(&aux, n);
|
setivalue(&aux, n);
|
||||||
luaV_finishset(L, t, &aux, s2v(L->top - 1), slot);
|
luaV_finishset(L, t, &aux, s2v(L->top.p - 1), slot);
|
||||||
}
|
}
|
||||||
L->top--; /* pop value */
|
L->top.p--; /* pop value */
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -896,16 +898,16 @@ static void aux_rawset (lua_State *L, int idx, TValue *key, int n) {
|
|||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, n);
|
api_checknelems(L, n);
|
||||||
t = gettable(L, idx);
|
t = gettable(L, idx);
|
||||||
luaH_set(L, t, key, s2v(L->top - 1));
|
luaH_set(L, t, key, s2v(L->top.p - 1));
|
||||||
invalidateTMcache(t);
|
invalidateTMcache(t);
|
||||||
luaC_barrierback(L, obj2gco(t), s2v(L->top - 1));
|
luaC_barrierback(L, obj2gco(t), s2v(L->top.p - 1));
|
||||||
L->top -= n;
|
L->top.p -= n;
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LUA_API void lua_rawset (lua_State *L, int idx) {
|
LUA_API void lua_rawset (lua_State *L, int idx) {
|
||||||
aux_rawset(L, idx, s2v(L->top - 2), 2);
|
aux_rawset(L, idx, s2v(L->top.p - 2), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -921,9 +923,9 @@ LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) {
|
|||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, 1);
|
api_checknelems(L, 1);
|
||||||
t = gettable(L, idx);
|
t = gettable(L, idx);
|
||||||
luaH_setint(L, t, n, s2v(L->top - 1));
|
luaH_setint(L, t, n, s2v(L->top.p - 1));
|
||||||
luaC_barrierback(L, obj2gco(t), s2v(L->top - 1));
|
luaC_barrierback(L, obj2gco(t), s2v(L->top.p - 1));
|
||||||
L->top--;
|
L->top.p--;
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -934,11 +936,11 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
|
|||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, 1);
|
api_checknelems(L, 1);
|
||||||
obj = index2value(L, objindex);
|
obj = index2value(L, objindex);
|
||||||
if (ttisnil(s2v(L->top - 1)))
|
if (ttisnil(s2v(L->top.p - 1)))
|
||||||
mt = NULL;
|
mt = NULL;
|
||||||
else {
|
else {
|
||||||
api_check(L, ttistable(s2v(L->top - 1)), "table expected");
|
api_check(L, ttistable(s2v(L->top.p - 1)), "table expected");
|
||||||
mt = hvalue(s2v(L->top - 1));
|
mt = hvalue(s2v(L->top.p - 1));
|
||||||
}
|
}
|
||||||
switch (ttype(obj)) {
|
switch (ttype(obj)) {
|
||||||
case LUA_TTABLE: {
|
case LUA_TTABLE: {
|
||||||
@ -962,7 +964,7 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
L->top--;
|
L->top.p--;
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -978,11 +980,11 @@ LUA_API int lua_setiuservalue (lua_State *L, int idx, int n) {
|
|||||||
if (!(cast_uint(n) - 1u < cast_uint(uvalue(o)->nuvalue)))
|
if (!(cast_uint(n) - 1u < cast_uint(uvalue(o)->nuvalue)))
|
||||||
res = 0; /* 'n' not in [1, uvalue(o)->nuvalue] */
|
res = 0; /* 'n' not in [1, uvalue(o)->nuvalue] */
|
||||||
else {
|
else {
|
||||||
setobj(L, &uvalue(o)->uv[n - 1].uv, s2v(L->top - 1));
|
setobj(L, &uvalue(o)->uv[n - 1].uv, s2v(L->top.p - 1));
|
||||||
luaC_barrierback(L, gcvalue(o), s2v(L->top - 1));
|
luaC_barrierback(L, gcvalue(o), s2v(L->top.p - 1));
|
||||||
res = 1;
|
res = 1;
|
||||||
}
|
}
|
||||||
L->top--;
|
L->top.p--;
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -994,7 +996,8 @@ LUA_API int lua_setiuservalue (lua_State *L, int idx, int n) {
|
|||||||
|
|
||||||
|
|
||||||
#define checkresults(L,na,nr) \
|
#define checkresults(L,na,nr) \
|
||||||
api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
|
api_check(L, (nr) == LUA_MULTRET \
|
||||||
|
|| (L->ci->top.p - L->top.p >= (nr) - (na)), \
|
||||||
"results from function overflow current stack size")
|
"results from function overflow current stack size")
|
||||||
|
|
||||||
|
|
||||||
@ -1007,7 +1010,7 @@ LUA_API void lua_callk (lua_State *L, int nargs, int nresults,
|
|||||||
api_checknelems(L, nargs+1);
|
api_checknelems(L, nargs+1);
|
||||||
api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
|
api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
|
||||||
checkresults(L, nargs, nresults);
|
checkresults(L, nargs, nresults);
|
||||||
func = L->top - (nargs+1);
|
func = L->top.p - (nargs+1);
|
||||||
if (k != NULL && yieldable(L)) { /* need to prepare continuation? */
|
if (k != NULL && yieldable(L)) { /* need to prepare continuation? */
|
||||||
L->ci->u.c.k = k; /* save continuation */
|
L->ci->u.c.k = k; /* save continuation */
|
||||||
L->ci->u.c.ctx = ctx; /* save context */
|
L->ci->u.c.ctx = ctx; /* save context */
|
||||||
@ -1055,7 +1058,7 @@ LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
|
|||||||
api_check(L, ttisfunction(s2v(o)), "error handler must be a function");
|
api_check(L, ttisfunction(s2v(o)), "error handler must be a function");
|
||||||
func = savestack(L, o);
|
func = savestack(L, o);
|
||||||
}
|
}
|
||||||
c.func = L->top - (nargs+1); /* function to be called */
|
c.func = L->top.p - (nargs+1); /* function to be called */
|
||||||
if (k == NULL || !yieldable(L)) { /* no continuation or no yieldable? */
|
if (k == NULL || !yieldable(L)) { /* no continuation or no yieldable? */
|
||||||
c.nresults = nresults; /* do a 'conventional' protected call */
|
c.nresults = nresults; /* do a 'conventional' protected call */
|
||||||
status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
|
status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
|
||||||
@ -1090,12 +1093,12 @@ 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(s2v(L->top - 1)); /* get newly created function */
|
LClosure *f = clLvalue(s2v(L->top.p - 1)); /* get new 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 */
|
||||||
const TValue *gt = getGtable(L);
|
const TValue *gt = getGtable(L);
|
||||||
/* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
|
/* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
|
||||||
setobj(L, f->upvals[0]->v, gt);
|
setobj(L, f->upvals[0]->v.p, gt);
|
||||||
luaC_barrier(L, f->upvals[0], gt);
|
luaC_barrier(L, f->upvals[0], gt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1109,7 +1112,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 = s2v(L->top - 1);
|
o = s2v(L->top.p - 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
|
||||||
@ -1235,7 +1238,7 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
|
|||||||
LUA_API int lua_error (lua_State *L) {
|
LUA_API int lua_error (lua_State *L) {
|
||||||
TValue *errobj;
|
TValue *errobj;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
errobj = s2v(L->top - 1);
|
errobj = s2v(L->top.p - 1);
|
||||||
api_checknelems(L, 1);
|
api_checknelems(L, 1);
|
||||||
/* error object is the memory error message? */
|
/* error object is the memory error message? */
|
||||||
if (ttisshrstring(errobj) && eqshrstr(tsvalue(errobj), G(L)->memerrmsg))
|
if (ttisshrstring(errobj) && eqshrstr(tsvalue(errobj), G(L)->memerrmsg))
|
||||||
@ -1253,12 +1256,12 @@ LUA_API int lua_next (lua_State *L, int idx) {
|
|||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checknelems(L, 1);
|
api_checknelems(L, 1);
|
||||||
t = gettable(L, idx);
|
t = gettable(L, idx);
|
||||||
more = luaH_next(L, t, L->top - 1);
|
more = luaH_next(L, t, L->top.p - 1);
|
||||||
if (more) {
|
if (more) {
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
}
|
}
|
||||||
else /* no more elements */
|
else /* no more elements */
|
||||||
L->top -= 1; /* remove key */
|
L->top.p -= 1; /* remove key */
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return more;
|
return more;
|
||||||
}
|
}
|
||||||
@ -1270,7 +1273,7 @@ LUA_API void lua_toclose (lua_State *L, int idx) {
|
|||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
o = index2stack(L, idx);
|
o = index2stack(L, idx);
|
||||||
nresults = L->ci->nresults;
|
nresults = L->ci->nresults;
|
||||||
api_check(L, L->tbclist < o, "given index below or equal a marked one");
|
api_check(L, L->tbclist.p < o, "given index below or equal a marked one");
|
||||||
luaF_newtbcupval(L, o); /* create new to-be-closed upvalue */
|
luaF_newtbcupval(L, o); /* create new to-be-closed upvalue */
|
||||||
if (!hastocloseCfunc(nresults)) /* function not marked yet? */
|
if (!hastocloseCfunc(nresults)) /* function not marked yet? */
|
||||||
L->ci->nresults = codeNresults(nresults); /* mark it */
|
L->ci->nresults = codeNresults(nresults); /* mark it */
|
||||||
@ -1285,7 +1288,7 @@ LUA_API void lua_concat (lua_State *L, int n) {
|
|||||||
if (n > 0)
|
if (n > 0)
|
||||||
luaV_concat(L, n);
|
luaV_concat(L, n);
|
||||||
else { /* nothing to concatenate */
|
else { /* nothing to concatenate */
|
||||||
setsvalue2s(L, L->top, luaS_newlstr(L, "", 0)); /* push empty string */
|
setsvalue2s(L, L->top.p, luaS_newlstr(L, "", 0)); /* push empty string */
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
}
|
}
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
@ -1297,7 +1300,7 @@ LUA_API void lua_len (lua_State *L, int idx) {
|
|||||||
TValue *t;
|
TValue *t;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
t = index2value(L, idx);
|
t = index2value(L, idx);
|
||||||
luaV_objlen(L, L->top, t);
|
luaV_objlen(L, L->top.p, t);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
@ -1342,7 +1345,7 @@ LUA_API void *lua_newuserdatauv (lua_State *L, size_t size, int nuvalue) {
|
|||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_check(L, 0 <= nuvalue && nuvalue < USHRT_MAX, "invalid value");
|
api_check(L, 0 <= nuvalue && nuvalue < USHRT_MAX, "invalid value");
|
||||||
u = luaS_newudata(L, size, nuvalue);
|
u = luaS_newudata(L, size, nuvalue);
|
||||||
setuvalue(L, s2v(L->top), u);
|
setuvalue(L, s2v(L->top.p), u);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
@ -1368,7 +1371,7 @@ static const char *aux_upvalue (TValue *fi, int n, TValue **val,
|
|||||||
Proto *p = f->p;
|
Proto *p = f->p;
|
||||||
if (!(cast_uint(n) - 1u < cast_uint(p->sizeupvalues)))
|
if (!(cast_uint(n) - 1u < cast_uint(p->sizeupvalues)))
|
||||||
return NULL; /* 'n' not in [1, p->sizeupvalues] */
|
return NULL; /* 'n' not in [1, p->sizeupvalues] */
|
||||||
*val = f->upvals[n-1]->v;
|
*val = f->upvals[n-1]->v.p;
|
||||||
if (owner) *owner = obj2gco(f->upvals[n - 1]);
|
if (owner) *owner = obj2gco(f->upvals[n - 1]);
|
||||||
name = p->upvalues[n-1].name;
|
name = p->upvalues[n-1].name;
|
||||||
return (name == NULL) ? "(no name)" : getstr(name);
|
return (name == NULL) ? "(no name)" : getstr(name);
|
||||||
@ -1384,7 +1387,7 @@ LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
|
|||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
name = aux_upvalue(index2value(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.p, val);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
}
|
}
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
@ -1402,8 +1405,8 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
|
|||||||
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.p--;
|
||||||
setobj(L, val, s2v(L->top));
|
setobj(L, val, s2v(L->top.p));
|
||||||
luaC_barrier(L, owner, val);
|
luaC_barrier(L, owner, val);
|
||||||
}
|
}
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
|
17
lapi.h
17
lapi.h
@ -12,23 +12,26 @@
|
|||||||
#include "lstate.h"
|
#include "lstate.h"
|
||||||
|
|
||||||
|
|
||||||
/* Increments 'L->top', checking for stack overflows */
|
/* Increments 'L->top.p', checking for stack overflows */
|
||||||
#define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \
|
#define api_incr_top(L) {L->top.p++; \
|
||||||
"stack overflow");}
|
api_check(L, L->top.p <= L->ci->top.p, \
|
||||||
|
"stack overflow");}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** If a call returns too many multiple returns, the callee may not have
|
** If a call returns too many multiple returns, the callee may not have
|
||||||
** stack space to accommodate all results. In this case, this macro
|
** stack space to accommodate all results. In this case, this macro
|
||||||
** increases its stack space ('L->ci->top').
|
** increases its stack space ('L->ci->top.p').
|
||||||
*/
|
*/
|
||||||
#define adjustresults(L,nres) \
|
#define adjustresults(L,nres) \
|
||||||
{ if ((nres) <= LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; }
|
{ if ((nres) <= LUA_MULTRET && L->ci->top.p < L->top.p) \
|
||||||
|
L->ci->top.p = L->top.p; }
|
||||||
|
|
||||||
|
|
||||||
/* Ensure the stack has at least 'n' elements */
|
/* Ensure the stack has at least 'n' elements */
|
||||||
#define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \
|
#define api_checknelems(L,n) \
|
||||||
"not enough elements in the stack")
|
api_check(L, (n) < (L->top.p - L->ci->func.p), \
|
||||||
|
"not enough elements in the stack")
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
52
ldebug.c
52
ldebug.c
@ -182,10 +182,10 @@ static const char *upvalname (const Proto *p, int uv) {
|
|||||||
|
|
||||||
|
|
||||||
static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
|
static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
|
||||||
if (clLvalue(s2v(ci->func))->p->is_vararg) {
|
if (clLvalue(s2v(ci->func.p))->p->is_vararg) {
|
||||||
int nextra = ci->u.l.nextraargs;
|
int nextra = ci->u.l.nextraargs;
|
||||||
if (n >= -nextra) { /* 'n' is negative */
|
if (n >= -nextra) { /* 'n' is negative */
|
||||||
*pos = ci->func - nextra - (n + 1);
|
*pos = ci->func.p - nextra - (n + 1);
|
||||||
return "(vararg)"; /* generic name for any vararg */
|
return "(vararg)"; /* generic name for any vararg */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -194,7 +194,7 @@ static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
|
|||||||
|
|
||||||
|
|
||||||
const char *luaG_findlocal (lua_State *L, CallInfo *ci, int n, StkId *pos) {
|
const char *luaG_findlocal (lua_State *L, CallInfo *ci, int n, StkId *pos) {
|
||||||
StkId base = ci->func + 1;
|
StkId base = ci->func.p + 1;
|
||||||
const char *name = NULL;
|
const char *name = NULL;
|
||||||
if (isLua(ci)) {
|
if (isLua(ci)) {
|
||||||
if (n < 0) /* access to vararg values? */
|
if (n < 0) /* access to vararg values? */
|
||||||
@ -203,7 +203,7 @@ const char *luaG_findlocal (lua_State *L, CallInfo *ci, int n, StkId *pos) {
|
|||||||
name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
|
name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
|
||||||
}
|
}
|
||||||
if (name == NULL) { /* no 'standard' name? */
|
if (name == NULL) { /* no 'standard' name? */
|
||||||
StkId limit = (ci == L->ci) ? L->top : ci->next->func;
|
StkId limit = (ci == L->ci) ? L->top.p : ci->next->func.p;
|
||||||
if (limit - base >= n && n > 0) { /* is 'n' inside 'ci' stack? */
|
if (limit - base >= n && n > 0) { /* is 'n' inside 'ci' stack? */
|
||||||
/* generic name for any valid slot */
|
/* generic name for any valid slot */
|
||||||
name = isLua(ci) ? "(temporary)" : "(C temporary)";
|
name = isLua(ci) ? "(temporary)" : "(C temporary)";
|
||||||
@ -221,16 +221,16 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
|
|||||||
const char *name;
|
const char *name;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
if (ar == NULL) { /* information about non-active function? */
|
if (ar == NULL) { /* information about non-active function? */
|
||||||
if (!isLfunction(s2v(L->top - 1))) /* not a Lua function? */
|
if (!isLfunction(s2v(L->top.p - 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(s2v(L->top - 1))->p, n, 0);
|
name = luaF_getlocalname(clLvalue(s2v(L->top.p - 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 = luaG_findlocal(L, ar->i_ci, n, &pos);
|
name = luaG_findlocal(L, ar->i_ci, n, &pos);
|
||||||
if (name) {
|
if (name) {
|
||||||
setobjs2s(L, L->top, pos);
|
setobjs2s(L, L->top.p, pos);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -245,8 +245,8 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
|
|||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
name = luaG_findlocal(L, ar->i_ci, n, &pos);
|
name = luaG_findlocal(L, ar->i_ci, n, &pos);
|
||||||
if (name) {
|
if (name) {
|
||||||
setobjs2s(L, pos, L->top - 1);
|
setobjs2s(L, pos, L->top.p - 1);
|
||||||
L->top--; /* pop value */
|
L->top.p--; /* pop value */
|
||||||
}
|
}
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return name;
|
return name;
|
||||||
@ -289,7 +289,7 @@ static int nextline (const 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(s2v(L->top));
|
setnilvalue(s2v(L->top.p));
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -298,7 +298,7 @@ static void collectvalidlines (lua_State *L, Closure *f) {
|
|||||||
const Proto *p = f->l.p;
|
const 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 */
|
||||||
sethvalue2s(L, L->top, t); /* push it on stack */
|
sethvalue2s(L, L->top.p, t); /* push it on stack */
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
setbtvalue(&v); /* boolean 'true' to be the value of all indices */
|
setbtvalue(&v); /* boolean 'true' to be the value of all indices */
|
||||||
if (!p->is_vararg) /* regular function? */
|
if (!p->is_vararg) /* regular function? */
|
||||||
@ -388,20 +388,20 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
|
|||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
if (*what == '>') {
|
if (*what == '>') {
|
||||||
ci = NULL;
|
ci = NULL;
|
||||||
func = s2v(L->top - 1);
|
func = s2v(L->top.p - 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.p--; /* pop function */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ci = ar->i_ci;
|
ci = ar->i_ci;
|
||||||
func = s2v(ci->func);
|
func = s2v(ci->func.p);
|
||||||
lua_assert(ttisfunction(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')) {
|
||||||
setobj2s(L, L->top, func);
|
setobj2s(L, L->top.p, func);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
}
|
}
|
||||||
if (strchr(what, 'L'))
|
if (strchr(what, 'L'))
|
||||||
@ -663,7 +663,7 @@ static const char *funcnamefromcall (lua_State *L, CallInfo *ci,
|
|||||||
*/
|
*/
|
||||||
static int isinstack (CallInfo *ci, const TValue *o) {
|
static int isinstack (CallInfo *ci, const TValue *o) {
|
||||||
StkId pos;
|
StkId pos;
|
||||||
for (pos = ci->func + 1; pos < ci->top; pos++) {
|
for (pos = ci->func.p + 1; pos < ci->top.p; pos++) {
|
||||||
if (o == s2v(pos))
|
if (o == s2v(pos))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -681,7 +681,7 @@ static const char *getupvalname (CallInfo *ci, const TValue *o,
|
|||||||
LClosure *c = ci_func(ci);
|
LClosure *c = ci_func(ci);
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < c->nupvalues; i++) {
|
for (i = 0; i < c->nupvalues; i++) {
|
||||||
if (c->upvals[i]->v == o) {
|
if (c->upvals[i]->v.p == o) {
|
||||||
*name = upvalname(c->p, i);
|
*name = upvalname(c->p, i);
|
||||||
return "upvalue";
|
return "upvalue";
|
||||||
}
|
}
|
||||||
@ -710,7 +710,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(cast(StkId, o) - (ci->func + 1)), &name);
|
cast_int(cast(StkId, o) - (ci->func.p + 1)), &name);
|
||||||
}
|
}
|
||||||
return formatvarinfo(L, kind, name);
|
return formatvarinfo(L, kind, name);
|
||||||
}
|
}
|
||||||
@ -807,10 +807,10 @@ l_noret luaG_errormsg (lua_State *L) {
|
|||||||
if (L->errfunc != 0) { /* is there an error handling function? */
|
if (L->errfunc != 0) { /* is there an error handling function? */
|
||||||
StkId errfunc = restorestack(L, L->errfunc);
|
StkId errfunc = restorestack(L, L->errfunc);
|
||||||
lua_assert(ttisfunction(s2v(errfunc)));
|
lua_assert(ttisfunction(s2v(errfunc)));
|
||||||
setobjs2s(L, L->top, L->top - 1); /* move argument */
|
setobjs2s(L, L->top.p, L->top.p - 1); /* move argument */
|
||||||
setobjs2s(L, L->top - 1, errfunc); /* push function */
|
setobjs2s(L, L->top.p - 1, errfunc); /* push function */
|
||||||
L->top++; /* assume EXTRA_STACK */
|
L->top.p++; /* assume EXTRA_STACK */
|
||||||
luaD_callnoyield(L, L->top - 2, 1); /* call it */
|
luaD_callnoyield(L, L->top.p - 2, 1); /* call it */
|
||||||
}
|
}
|
||||||
luaD_throw(L, LUA_ERRRUN);
|
luaD_throw(L, LUA_ERRRUN);
|
||||||
}
|
}
|
||||||
@ -826,8 +826,8 @@ l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
|
|||||||
va_end(argp);
|
va_end(argp);
|
||||||
if (isLua(ci)) { /* if Lua function, add source:line information */
|
if (isLua(ci)) { /* if Lua function, add source:line information */
|
||||||
luaG_addinfo(L, msg, ci_func(ci)->p->source, getcurrentline(ci));
|
luaG_addinfo(L, msg, ci_func(ci)->p->source, getcurrentline(ci));
|
||||||
setobjs2s(L, L->top - 2, L->top - 1); /* remove 'msg' from the stack */
|
setobjs2s(L, L->top.p - 2, L->top.p - 1); /* remove 'msg' */
|
||||||
L->top--;
|
L->top.p--;
|
||||||
}
|
}
|
||||||
luaG_errormsg(L);
|
luaG_errormsg(L);
|
||||||
}
|
}
|
||||||
@ -872,7 +872,7 @@ static int changedline (const Proto *p, int oldpc, int newpc) {
|
|||||||
** invalid; if so, use zero as a valid value. (A wrong but valid 'oldpc'
|
** invalid; if so, use zero as a valid value. (A wrong but valid 'oldpc'
|
||||||
** at most causes an extra call to a line hook.)
|
** at most causes an extra call to a line hook.)
|
||||||
** This function is not "Protected" when called, so it should correct
|
** This function is not "Protected" when called, so it should correct
|
||||||
** 'L->top' before calling anything that can run the GC.
|
** 'L->top.p' before calling anything that can run the GC.
|
||||||
*/
|
*/
|
||||||
int luaG_traceexec (lua_State *L, const Instruction *pc) {
|
int luaG_traceexec (lua_State *L, const Instruction *pc) {
|
||||||
CallInfo *ci = L->ci;
|
CallInfo *ci = L->ci;
|
||||||
@ -895,7 +895,7 @@ int luaG_traceexec (lua_State *L, const Instruction *pc) {
|
|||||||
return 1; /* do not call hook again (VM yielded, so it did not move) */
|
return 1; /* do not call hook again (VM yielded, so it did not move) */
|
||||||
}
|
}
|
||||||
if (!isIT(*(ci->u.l.savedpc - 1))) /* top not being used? */
|
if (!isIT(*(ci->u.l.savedpc - 1))) /* top not being used? */
|
||||||
L->top = ci->top; /* correct top */
|
L->top.p = ci->top.p; /* correct top */
|
||||||
if (counthook)
|
if (counthook)
|
||||||
luaD_hook(L, LUA_HOOKCOUNT, -1, 0, 0); /* call count hook */
|
luaD_hook(L, LUA_HOOKCOUNT, -1, 0, 0); /* call count hook */
|
||||||
if (mask & LUA_MASKLINE) {
|
if (mask & LUA_MASKLINE) {
|
||||||
|
2
ldebug.h
2
ldebug.h
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/* Active Lua function (given call info) */
|
/* Active Lua function (given call info) */
|
||||||
#define ci_func(ci) (clLvalue(s2v((ci)->func)))
|
#define ci_func(ci) (clLvalue(s2v((ci)->func.p)))
|
||||||
|
|
||||||
|
|
||||||
#define resethookcount(L) (L->hookcount = L->basehookcount)
|
#define resethookcount(L) (L->hookcount = L->basehookcount)
|
||||||
|
125
ldo.c
125
ldo.c
@ -104,11 +104,11 @@ void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) {
|
|||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
lua_assert(errorstatus(errcode)); /* real error */
|
lua_assert(errorstatus(errcode)); /* real error */
|
||||||
setobjs2s(L, oldtop, L->top - 1); /* error message on current top */
|
setobjs2s(L, oldtop, L->top.p - 1); /* error message on current top */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
L->top = oldtop + 1;
|
L->top.p = oldtop + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -121,7 +121,7 @@ l_noret luaD_throw (lua_State *L, int errcode) {
|
|||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
errcode = luaE_resetthread(L, errcode); /* close all upvalues */
|
errcode = luaE_resetthread(L, errcode); /* close all upvalues */
|
||||||
if (g->mainthread->errorJmp) { /* main thread has a handler? */
|
if (g->mainthread->errorJmp) { /* main thread has a handler? */
|
||||||
setobjs2s(L, g->mainthread->top++, L->top - 1); /* copy error obj. */
|
setobjs2s(L, g->mainthread->top.p++, L->top.p - 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 */
|
||||||
@ -160,13 +160,13 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
|
|||||||
static void correctstack (lua_State *L, StkId oldstack, StkId newstack) {
|
static void correctstack (lua_State *L, StkId oldstack, StkId newstack) {
|
||||||
CallInfo *ci;
|
CallInfo *ci;
|
||||||
UpVal *up;
|
UpVal *up;
|
||||||
L->top = (L->top - oldstack) + newstack;
|
L->top.p = (L->top.p - oldstack) + newstack;
|
||||||
L->tbclist = (L->tbclist - oldstack) + newstack;
|
L->tbclist.p = (L->tbclist.p - oldstack) + newstack;
|
||||||
for (up = L->openupval; up != NULL; up = up->u.open.next)
|
for (up = L->openupval; up != NULL; up = up->u.open.next)
|
||||||
up->v = s2v((uplevel(up) - oldstack) + newstack);
|
up->v.p = s2v((uplevel(up) - oldstack) + newstack);
|
||||||
for (ci = L->ci; ci != NULL; ci = ci->previous) {
|
for (ci = L->ci; ci != NULL; ci = ci->previous) {
|
||||||
ci->top = (ci->top - oldstack) + newstack;
|
ci->top.p = (ci->top.p - oldstack) + newstack;
|
||||||
ci->func = (ci->func - oldstack) + newstack;
|
ci->func.p = (ci->func.p - oldstack) + newstack;
|
||||||
if (isLua(ci))
|
if (isLua(ci))
|
||||||
ci->u.l.trap = 1; /* signal to update 'trap' in 'luaV_execute' */
|
ci->u.l.trap = 1; /* signal to update 'trap' in 'luaV_execute' */
|
||||||
}
|
}
|
||||||
@ -176,7 +176,6 @@ static void correctstack (lua_State *L, StkId oldstack, StkId newstack) {
|
|||||||
/* some space for error handling */
|
/* some space for error handling */
|
||||||
#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200)
|
#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Reallocate the stack to a new size, correcting all pointers into
|
** Reallocate the stack to a new size, correcting all pointers into
|
||||||
** it. (There are pointers to a stack from its upvalues, from its list
|
** it. (There are pointers to a stack from its upvalues, from its list
|
||||||
@ -201,13 +200,13 @@ int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) {
|
|||||||
}
|
}
|
||||||
/* number of elements to be copied to the new stack */
|
/* number of elements to be copied to the new stack */
|
||||||
i = ((oldsize <= newsize) ? oldsize : newsize) + EXTRA_STACK;
|
i = ((oldsize <= newsize) ? oldsize : newsize) + EXTRA_STACK;
|
||||||
memcpy(newstack, L->stack, i * sizeof(StackValue));
|
memcpy(newstack, L->stack.p, i * sizeof(StackValue));
|
||||||
for (; i < newsize + EXTRA_STACK; i++)
|
for (; i < newsize + EXTRA_STACK; i++)
|
||||||
setnilvalue(s2v(newstack + i)); /* erase new segment */
|
setnilvalue(s2v(newstack + i)); /* erase new segment */
|
||||||
correctstack(L, L->stack, newstack);
|
correctstack(L, L->stack.p, newstack);
|
||||||
luaM_freearray(L, L->stack, oldsize + EXTRA_STACK);
|
luaM_freearray(L, L->stack.p, oldsize + EXTRA_STACK);
|
||||||
L->stack = newstack;
|
L->stack.p = newstack;
|
||||||
L->stack_last = L->stack + newsize;
|
L->stack_last.p = L->stack.p + newsize;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +228,7 @@ int luaD_growstack (lua_State *L, int n, int raiseerror) {
|
|||||||
}
|
}
|
||||||
else if (n < LUAI_MAXSTACK) { /* avoids arithmetic overflows */
|
else if (n < LUAI_MAXSTACK) { /* avoids arithmetic overflows */
|
||||||
int newsize = 2 * size; /* tentative new size */
|
int newsize = 2 * size; /* tentative new size */
|
||||||
int needed = cast_int(L->top - L->stack) + n;
|
int needed = cast_int(L->top.p - L->stack.p) + n;
|
||||||
if (newsize > LUAI_MAXSTACK) /* cannot cross the limit */
|
if (newsize > LUAI_MAXSTACK) /* cannot cross the limit */
|
||||||
newsize = LUAI_MAXSTACK;
|
newsize = LUAI_MAXSTACK;
|
||||||
if (newsize < needed) /* but must respect what was asked for */
|
if (newsize < needed) /* but must respect what was asked for */
|
||||||
@ -253,12 +252,12 @@ int luaD_growstack (lua_State *L, int n, int raiseerror) {
|
|||||||
static int stackinuse (lua_State *L) {
|
static int stackinuse (lua_State *L) {
|
||||||
CallInfo *ci;
|
CallInfo *ci;
|
||||||
int res;
|
int res;
|
||||||
StkId lim = L->top;
|
StkId lim = L->top.p;
|
||||||
for (ci = L->ci; ci != NULL; ci = ci->previous) {
|
for (ci = L->ci; ci != NULL; ci = ci->previous) {
|
||||||
if (lim < ci->top) lim = ci->top;
|
if (lim < ci->top.p) lim = ci->top.p;
|
||||||
}
|
}
|
||||||
lua_assert(lim <= L->stack_last + EXTRA_STACK);
|
lua_assert(lim <= L->stack_last.p + EXTRA_STACK);
|
||||||
res = cast_int(lim - L->stack) + 1; /* part of stack in use */
|
res = cast_int(lim - L->stack.p) + 1; /* part of stack in use */
|
||||||
if (res < LUA_MINSTACK)
|
if (res < LUA_MINSTACK)
|
||||||
res = LUA_MINSTACK; /* ensure a minimum size */
|
res = LUA_MINSTACK; /* ensure a minimum size */
|
||||||
return res;
|
return res;
|
||||||
@ -295,7 +294,7 @@ void luaD_shrinkstack (lua_State *L) {
|
|||||||
|
|
||||||
void luaD_inctop (lua_State *L) {
|
void luaD_inctop (lua_State *L) {
|
||||||
luaD_checkstack(L, 1);
|
luaD_checkstack(L, 1);
|
||||||
L->top++;
|
L->top.p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* }================================================================== */
|
/* }================================================================== */
|
||||||
@ -312,8 +311,8 @@ void luaD_hook (lua_State *L, int event, int line,
|
|||||||
if (hook && L->allowhook) { /* make sure there is a hook */
|
if (hook && L->allowhook) { /* make sure there is a hook */
|
||||||
int mask = CIST_HOOKED;
|
int mask = CIST_HOOKED;
|
||||||
CallInfo *ci = L->ci;
|
CallInfo *ci = L->ci;
|
||||||
ptrdiff_t top = savestack(L, L->top); /* preserve original 'top' */
|
ptrdiff_t top = savestack(L, L->top.p); /* preserve original 'top' */
|
||||||
ptrdiff_t ci_top = savestack(L, ci->top); /* idem for 'ci->top' */
|
ptrdiff_t ci_top = savestack(L, ci->top.p); /* idem for 'ci->top' */
|
||||||
lua_Debug ar;
|
lua_Debug ar;
|
||||||
ar.event = event;
|
ar.event = event;
|
||||||
ar.currentline = line;
|
ar.currentline = line;
|
||||||
@ -323,11 +322,11 @@ void luaD_hook (lua_State *L, int event, int line,
|
|||||||
ci->u2.transferinfo.ftransfer = ftransfer;
|
ci->u2.transferinfo.ftransfer = ftransfer;
|
||||||
ci->u2.transferinfo.ntransfer = ntransfer;
|
ci->u2.transferinfo.ntransfer = ntransfer;
|
||||||
}
|
}
|
||||||
if (isLua(ci) && L->top < ci->top)
|
if (isLua(ci) && L->top.p < ci->top.p)
|
||||||
L->top = ci->top; /* protect entire activation register */
|
L->top.p = ci->top.p; /* protect entire activation register */
|
||||||
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
|
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
|
||||||
if (ci->top < L->top + LUA_MINSTACK)
|
if (ci->top.p < L->top.p + LUA_MINSTACK)
|
||||||
ci->top = L->top + LUA_MINSTACK;
|
ci->top.p = L->top.p + LUA_MINSTACK;
|
||||||
L->allowhook = 0; /* cannot call hooks inside a hook */
|
L->allowhook = 0; /* cannot call hooks inside a hook */
|
||||||
ci->callstatus |= mask;
|
ci->callstatus |= mask;
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
@ -335,8 +334,8 @@ void luaD_hook (lua_State *L, int event, int line,
|
|||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
lua_assert(!L->allowhook);
|
lua_assert(!L->allowhook);
|
||||||
L->allowhook = 1;
|
L->allowhook = 1;
|
||||||
ci->top = restorestack(L, ci_top);
|
ci->top.p = restorestack(L, ci_top);
|
||||||
L->top = restorestack(L, top);
|
L->top.p = restorestack(L, top);
|
||||||
ci->callstatus &= ~mask;
|
ci->callstatus &= ~mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -367,7 +366,7 @@ void luaD_hookcall (lua_State *L, CallInfo *ci) {
|
|||||||
*/
|
*/
|
||||||
static void rethook (lua_State *L, CallInfo *ci, int nres) {
|
static void rethook (lua_State *L, CallInfo *ci, int nres) {
|
||||||
if (L->hookmask & LUA_MASKRET) { /* is return hook on? */
|
if (L->hookmask & LUA_MASKRET) { /* is return hook on? */
|
||||||
StkId firstres = L->top - nres; /* index of first result */
|
StkId firstres = L->top.p - nres; /* index of first result */
|
||||||
int delta = 0; /* correction for vararg functions */
|
int delta = 0; /* correction for vararg functions */
|
||||||
int ftransfer;
|
int ftransfer;
|
||||||
if (isLua(ci)) {
|
if (isLua(ci)) {
|
||||||
@ -375,10 +374,10 @@ static void rethook (lua_State *L, CallInfo *ci, int nres) {
|
|||||||
if (p->is_vararg)
|
if (p->is_vararg)
|
||||||
delta = ci->u.l.nextraargs + p->numparams + 1;
|
delta = ci->u.l.nextraargs + p->numparams + 1;
|
||||||
}
|
}
|
||||||
ci->func += delta; /* if vararg, back to virtual 'func' */
|
ci->func.p += delta; /* if vararg, back to virtual 'func' */
|
||||||
ftransfer = cast(unsigned short, firstres - ci->func);
|
ftransfer = cast(unsigned short, firstres - ci->func.p);
|
||||||
luaD_hook(L, LUA_HOOKRET, -1, ftransfer, nres); /* call it */
|
luaD_hook(L, LUA_HOOKRET, -1, ftransfer, nres); /* call it */
|
||||||
ci->func -= delta;
|
ci->func.p -= delta;
|
||||||
}
|
}
|
||||||
if (isLua(ci = ci->previous))
|
if (isLua(ci = ci->previous))
|
||||||
L->oldpc = pcRel(ci->u.l.savedpc, ci_func(ci)->p); /* set 'oldpc' */
|
L->oldpc = pcRel(ci->u.l.savedpc, ci_func(ci)->p); /* set 'oldpc' */
|
||||||
@ -397,9 +396,9 @@ StkId luaD_tryfuncTM (lua_State *L, StkId func) {
|
|||||||
tm = luaT_gettmbyobj(L, s2v(func), TM_CALL); /* (after previous GC) */
|
tm = luaT_gettmbyobj(L, s2v(func), TM_CALL); /* (after previous GC) */
|
||||||
if (l_unlikely(ttisnil(tm)))
|
if (l_unlikely(ttisnil(tm)))
|
||||||
luaG_callerror(L, s2v(func)); /* nothing to call */
|
luaG_callerror(L, s2v(func)); /* nothing to call */
|
||||||
for (p = L->top; p > func; p--) /* open space for metamethod */
|
for (p = L->top.p; p > func; p--) /* open space for metamethod */
|
||||||
setobjs2s(L, p, p-1);
|
setobjs2s(L, p, p-1);
|
||||||
L->top++; /* stack space pre-allocated by the caller */
|
L->top.p++; /* stack space pre-allocated by the caller */
|
||||||
setobj2s(L, func, tm); /* metamethod is the new function to be called */
|
setobj2s(L, func, tm); /* metamethod is the new function to be called */
|
||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
@ -416,14 +415,14 @@ l_sinline void moveresults (lua_State *L, StkId res, int nres, int wanted) {
|
|||||||
int i;
|
int i;
|
||||||
switch (wanted) { /* handle typical cases separately */
|
switch (wanted) { /* handle typical cases separately */
|
||||||
case 0: /* no values needed */
|
case 0: /* no values needed */
|
||||||
L->top = res;
|
L->top.p = res;
|
||||||
return;
|
return;
|
||||||
case 1: /* one value needed */
|
case 1: /* one value needed */
|
||||||
if (nres == 0) /* no results? */
|
if (nres == 0) /* no results? */
|
||||||
setnilvalue(s2v(res)); /* adjust with nil */
|
setnilvalue(s2v(res)); /* adjust with nil */
|
||||||
else /* at least one result */
|
else /* at least one result */
|
||||||
setobjs2s(L, res, L->top - nres); /* move it to proper place */
|
setobjs2s(L, res, L->top.p - nres); /* move it to proper place */
|
||||||
L->top = res + 1;
|
L->top.p = res + 1;
|
||||||
return;
|
return;
|
||||||
case LUA_MULTRET:
|
case LUA_MULTRET:
|
||||||
wanted = nres; /* we want all results */
|
wanted = nres; /* we want all results */
|
||||||
@ -446,14 +445,14 @@ l_sinline void moveresults (lua_State *L, StkId res, int nres, int wanted) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* generic case */
|
/* generic case */
|
||||||
firstresult = L->top - nres; /* index of first result */
|
firstresult = L->top.p - nres; /* index of first result */
|
||||||
if (nres > wanted) /* extra results? */
|
if (nres > wanted) /* extra results? */
|
||||||
nres = wanted; /* don't need them */
|
nres = wanted; /* don't need them */
|
||||||
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(s2v(res + i));
|
setnilvalue(s2v(res + i));
|
||||||
L->top = res + wanted; /* top points after the last result */
|
L->top.p = res + wanted; /* top points after the last result */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -468,7 +467,7 @@ void luaD_poscall (lua_State *L, CallInfo *ci, int nres) {
|
|||||||
if (l_unlikely(L->hookmask && !hastocloseCfunc(wanted)))
|
if (l_unlikely(L->hookmask && !hastocloseCfunc(wanted)))
|
||||||
rethook(L, ci, nres);
|
rethook(L, ci, nres);
|
||||||
/* move results to proper place */
|
/* move results to proper place */
|
||||||
moveresults(L, ci->func, nres, wanted);
|
moveresults(L, ci->func.p, nres, wanted);
|
||||||
/* function cannot be in any of these cases when returning */
|
/* function cannot be in any of these cases when returning */
|
||||||
lua_assert(!(ci->callstatus &
|
lua_assert(!(ci->callstatus &
|
||||||
(CIST_HOOKED | CIST_YPCALL | CIST_FIN | CIST_TRAN | CIST_CLSRET)));
|
(CIST_HOOKED | CIST_YPCALL | CIST_FIN | CIST_TRAN | CIST_CLSRET)));
|
||||||
@ -483,10 +482,10 @@ void luaD_poscall (lua_State *L, CallInfo *ci, int nres) {
|
|||||||
l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, int nret,
|
l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, int nret,
|
||||||
int mask, StkId top) {
|
int mask, StkId top) {
|
||||||
CallInfo *ci = L->ci = next_ci(L); /* new frame */
|
CallInfo *ci = L->ci = next_ci(L); /* new frame */
|
||||||
ci->func = func;
|
ci->func.p = func;
|
||||||
ci->nresults = nret;
|
ci->nresults = nret;
|
||||||
ci->callstatus = mask;
|
ci->callstatus = mask;
|
||||||
ci->top = top;
|
ci->top.p = top;
|
||||||
return ci;
|
return ci;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -500,10 +499,10 @@ l_sinline int precallC (lua_State *L, StkId func, int nresults,
|
|||||||
CallInfo *ci;
|
CallInfo *ci;
|
||||||
checkstackGCp(L, LUA_MINSTACK, func); /* ensure minimum stack size */
|
checkstackGCp(L, LUA_MINSTACK, func); /* ensure minimum stack size */
|
||||||
L->ci = ci = prepCallInfo(L, func, nresults, CIST_C,
|
L->ci = ci = prepCallInfo(L, func, nresults, CIST_C,
|
||||||
L->top + LUA_MINSTACK);
|
L->top.p + LUA_MINSTACK);
|
||||||
lua_assert(ci->top <= L->stack_last);
|
lua_assert(ci->top.p <= L->stack_last.p);
|
||||||
if (l_unlikely(L->hookmask & LUA_MASKCALL)) {
|
if (l_unlikely(L->hookmask & LUA_MASKCALL)) {
|
||||||
int narg = cast_int(L->top - func) - 1;
|
int narg = cast_int(L->top.p - func) - 1;
|
||||||
luaD_hook(L, LUA_HOOKCALL, -1, 1, narg);
|
luaD_hook(L, LUA_HOOKCALL, -1, 1, narg);
|
||||||
}
|
}
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
@ -535,17 +534,17 @@ int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func,
|
|||||||
int nfixparams = p->numparams;
|
int nfixparams = p->numparams;
|
||||||
int i;
|
int i;
|
||||||
checkstackGCp(L, fsize - delta, func);
|
checkstackGCp(L, fsize - delta, func);
|
||||||
ci->func -= delta; /* restore 'func' (if vararg) */
|
ci->func.p -= delta; /* restore 'func' (if vararg) */
|
||||||
for (i = 0; i < narg1; i++) /* move down function and arguments */
|
for (i = 0; i < narg1; i++) /* move down function and arguments */
|
||||||
setobjs2s(L, ci->func + i, func + i);
|
setobjs2s(L, ci->func.p + i, func + i);
|
||||||
func = ci->func; /* moved-down function */
|
func = ci->func.p; /* moved-down function */
|
||||||
for (; narg1 <= nfixparams; narg1++)
|
for (; narg1 <= nfixparams; narg1++)
|
||||||
setnilvalue(s2v(func + narg1)); /* complete missing arguments */
|
setnilvalue(s2v(func + narg1)); /* complete missing arguments */
|
||||||
ci->top = func + 1 + fsize; /* top for new function */
|
ci->top.p = func + 1 + fsize; /* top for new function */
|
||||||
lua_assert(ci->top <= L->stack_last);
|
lua_assert(ci->top.p <= L->stack_last.p);
|
||||||
ci->u.l.savedpc = p->code; /* starting point */
|
ci->u.l.savedpc = p->code; /* starting point */
|
||||||
ci->callstatus |= CIST_TAIL;
|
ci->callstatus |= CIST_TAIL;
|
||||||
L->top = func + narg1; /* set top */
|
L->top.p = func + narg1; /* set top */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
default: { /* not a function */
|
default: { /* not a function */
|
||||||
@ -578,15 +577,15 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
|
|||||||
case LUA_VLCL: { /* Lua function */
|
case LUA_VLCL: { /* Lua function */
|
||||||
CallInfo *ci;
|
CallInfo *ci;
|
||||||
Proto *p = clLvalue(s2v(func))->p;
|
Proto *p = clLvalue(s2v(func))->p;
|
||||||
int narg = cast_int(L->top - func) - 1; /* number of real arguments */
|
int narg = cast_int(L->top.p - func) - 1; /* number of real arguments */
|
||||||
int nfixparams = p->numparams;
|
int nfixparams = p->numparams;
|
||||||
int fsize = p->maxstacksize; /* frame size */
|
int fsize = p->maxstacksize; /* frame size */
|
||||||
checkstackGCp(L, fsize, func);
|
checkstackGCp(L, fsize, func);
|
||||||
L->ci = ci = prepCallInfo(L, func, nresults, 0, func + 1 + fsize);
|
L->ci = ci = prepCallInfo(L, func, nresults, 0, func + 1 + fsize);
|
||||||
ci->u.l.savedpc = p->code; /* starting point */
|
ci->u.l.savedpc = p->code; /* starting point */
|
||||||
for (; narg < nfixparams; narg++)
|
for (; narg < nfixparams; narg++)
|
||||||
setnilvalue(s2v(L->top++)); /* complete missing arguments */
|
setnilvalue(s2v(L->top.p++)); /* complete missing arguments */
|
||||||
lua_assert(ci->top <= L->stack_last);
|
lua_assert(ci->top.p <= L->stack_last.p);
|
||||||
return ci;
|
return ci;
|
||||||
}
|
}
|
||||||
default: { /* not a function */
|
default: { /* not a function */
|
||||||
@ -748,8 +747,8 @@ static CallInfo *findpcall (lua_State *L) {
|
|||||||
** coroutine error handler and should not kill the coroutine.)
|
** coroutine error handler and should not kill the coroutine.)
|
||||||
*/
|
*/
|
||||||
static int resume_error (lua_State *L, const char *msg, int narg) {
|
static int resume_error (lua_State *L, const char *msg, int narg) {
|
||||||
L->top -= narg; /* remove args from the stack */
|
L->top.p -= narg; /* remove args from the stack */
|
||||||
setsvalue2s(L, L->top, luaS_new(L, msg)); /* push error message */
|
setsvalue2s(L, L->top.p, luaS_new(L, msg)); /* push error message */
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return LUA_ERRRUN;
|
return LUA_ERRRUN;
|
||||||
@ -765,7 +764,7 @@ static int resume_error (lua_State *L, const char *msg, int narg) {
|
|||||||
*/
|
*/
|
||||||
static void resume (lua_State *L, void *ud) {
|
static void resume (lua_State *L, void *ud) {
|
||||||
int n = *(cast(int*, ud)); /* number of arguments */
|
int n = *(cast(int*, ud)); /* number of arguments */
|
||||||
StkId firstArg = L->top - n; /* first argument */
|
StkId firstArg = L->top.p - n; /* first argument */
|
||||||
CallInfo *ci = L->ci;
|
CallInfo *ci = L->ci;
|
||||||
if (L->status == LUA_OK) /* starting a coroutine? */
|
if (L->status == LUA_OK) /* starting a coroutine? */
|
||||||
ccall(L, firstArg - 1, LUA_MULTRET, 0); /* just call its body */
|
ccall(L, firstArg - 1, LUA_MULTRET, 0); /* just call its body */
|
||||||
@ -773,7 +772,7 @@ static void resume (lua_State *L, void *ud) {
|
|||||||
lua_assert(L->status == LUA_YIELD);
|
lua_assert(L->status == LUA_YIELD);
|
||||||
L->status = LUA_OK; /* mark that it is running (again) */
|
L->status = LUA_OK; /* mark that it is running (again) */
|
||||||
if (isLua(ci)) { /* yielded inside a hook? */
|
if (isLua(ci)) { /* yielded inside a hook? */
|
||||||
L->top = firstArg; /* discard arguments */
|
L->top.p = firstArg; /* discard arguments */
|
||||||
luaV_execute(L, ci); /* just continue running Lua code */
|
luaV_execute(L, ci); /* just continue running Lua code */
|
||||||
}
|
}
|
||||||
else { /* 'common' yield */
|
else { /* 'common' yield */
|
||||||
@ -816,7 +815,7 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs,
|
|||||||
if (L->status == LUA_OK) { /* may be starting a coroutine */
|
if (L->status == LUA_OK) { /* may be starting a coroutine */
|
||||||
if (L->ci != &L->base_ci) /* not in base level? */
|
if (L->ci != &L->base_ci) /* not in base level? */
|
||||||
return resume_error(L, "cannot resume non-suspended coroutine", nargs);
|
return resume_error(L, "cannot resume non-suspended coroutine", nargs);
|
||||||
else if (L->top - (L->ci->func + 1) == nargs) /* no function? */
|
else if (L->top.p - (L->ci->func.p + 1) == nargs) /* no function? */
|
||||||
return resume_error(L, "cannot resume dead coroutine", nargs);
|
return resume_error(L, "cannot resume dead coroutine", nargs);
|
||||||
}
|
}
|
||||||
else if (L->status != LUA_YIELD) /* ended with errors? */
|
else if (L->status != LUA_YIELD) /* ended with errors? */
|
||||||
@ -834,11 +833,11 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs,
|
|||||||
lua_assert(status == L->status); /* normal end or yield */
|
lua_assert(status == L->status); /* normal end or yield */
|
||||||
else { /* unrecoverable error */
|
else { /* unrecoverable error */
|
||||||
L->status = cast_byte(status); /* mark thread as 'dead' */
|
L->status = cast_byte(status); /* mark thread as 'dead' */
|
||||||
luaD_seterrorobj(L, status, L->top); /* push error message */
|
luaD_seterrorobj(L, status, L->top.p); /* push error message */
|
||||||
L->ci->top = L->top;
|
L->ci->top.p = L->top.p;
|
||||||
}
|
}
|
||||||
*nresults = (status == LUA_YIELD) ? L->ci->u2.nyield
|
*nresults = (status == LUA_YIELD) ? L->ci->u2.nyield
|
||||||
: cast_int(L->top - (L->ci->func + 1));
|
: cast_int(L->top.p - (L->ci->func.p + 1));
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -993,7 +992,7 @@ int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
|
|||||||
p.dyd.gt.arr = NULL; p.dyd.gt.size = 0;
|
p.dyd.gt.arr = NULL; p.dyd.gt.size = 0;
|
||||||
p.dyd.label.arr = NULL; p.dyd.label.size = 0;
|
p.dyd.label.arr = NULL; p.dyd.label.size = 0;
|
||||||
luaZ_initbuffer(L, &p.buff);
|
luaZ_initbuffer(L, &p.buff);
|
||||||
status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc);
|
status = luaD_pcall(L, f_parser, &p, savestack(L, L->top.p), L->errfunc);
|
||||||
luaZ_freebuffer(L, &p.buff);
|
luaZ_freebuffer(L, &p.buff);
|
||||||
luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size);
|
luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size);
|
||||||
luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size);
|
luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size);
|
||||||
|
7
ldo.h
7
ldo.h
@ -8,6 +8,7 @@
|
|||||||
#define ldo_h
|
#define ldo_h
|
||||||
|
|
||||||
|
|
||||||
|
#include "llimits.h"
|
||||||
#include "lobject.h"
|
#include "lobject.h"
|
||||||
#include "lstate.h"
|
#include "lstate.h"
|
||||||
#include "lzio.h"
|
#include "lzio.h"
|
||||||
@ -23,7 +24,7 @@
|
|||||||
** at every check.
|
** at every check.
|
||||||
*/
|
*/
|
||||||
#define luaD_checkstackaux(L,n,pre,pos) \
|
#define luaD_checkstackaux(L,n,pre,pos) \
|
||||||
if (l_unlikely(L->stack_last - L->top <= (n))) \
|
if (l_unlikely(L->stack_last.p - L->top.p <= (n))) \
|
||||||
{ pre; luaD_growstack(L, n, 1); pos; } \
|
{ pre; luaD_growstack(L, n, 1); pos; } \
|
||||||
else { condmovestack(L,pre,pos); }
|
else { condmovestack(L,pre,pos); }
|
||||||
|
|
||||||
@ -32,8 +33,8 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define savestack(L,p) ((char *)(p) - (char *)L->stack)
|
#define savestack(L,pt) (cast_charp(pt) - cast_charp(L->stack.p))
|
||||||
#define restorestack(L,n) ((StkId)((char *)L->stack + (n)))
|
#define restorestack(L,n) cast(StkId, cast_charp(L->stack.p) + (n))
|
||||||
|
|
||||||
|
|
||||||
/* macro to check stack size, preserving 'p' */
|
/* macro to check stack size, preserving 'p' */
|
||||||
|
42
lfunc.c
42
lfunc.c
@ -50,8 +50,8 @@ void luaF_initupvals (lua_State *L, LClosure *cl) {
|
|||||||
for (i = 0; i < cl->nupvalues; i++) {
|
for (i = 0; i < cl->nupvalues; i++) {
|
||||||
GCObject *o = luaC_newobj(L, LUA_VUPVAL, sizeof(UpVal));
|
GCObject *o = luaC_newobj(L, LUA_VUPVAL, sizeof(UpVal));
|
||||||
UpVal *uv = gco2upv(o);
|
UpVal *uv = gco2upv(o);
|
||||||
uv->v = &uv->u.value; /* make it closed */
|
uv->v.p = &uv->u.value; /* make it closed */
|
||||||
setnilvalue(uv->v);
|
setnilvalue(uv->v.p);
|
||||||
cl->upvals[i] = uv;
|
cl->upvals[i] = uv;
|
||||||
luaC_objbarrier(L, cl, uv);
|
luaC_objbarrier(L, cl, uv);
|
||||||
}
|
}
|
||||||
@ -66,7 +66,7 @@ static UpVal *newupval (lua_State *L, int tbc, StkId level, UpVal **prev) {
|
|||||||
GCObject *o = luaC_newobj(L, LUA_VUPVAL, sizeof(UpVal));
|
GCObject *o = luaC_newobj(L, LUA_VUPVAL, sizeof(UpVal));
|
||||||
UpVal *uv = gco2upv(o);
|
UpVal *uv = gco2upv(o);
|
||||||
UpVal *next = *prev;
|
UpVal *next = *prev;
|
||||||
uv->v = s2v(level); /* current value lives in the stack */
|
uv->v.p = s2v(level); /* current value lives in the stack */
|
||||||
uv->tbc = tbc;
|
uv->tbc = tbc;
|
||||||
uv->u.open.next = next; /* link it to list of open upvalues */
|
uv->u.open.next = next; /* link it to list of open upvalues */
|
||||||
uv->u.open.previous = prev;
|
uv->u.open.previous = prev;
|
||||||
@ -106,12 +106,12 @@ UpVal *luaF_findupval (lua_State *L, StkId level) {
|
|||||||
** (This function assumes EXTRA_STACK.)
|
** (This function assumes EXTRA_STACK.)
|
||||||
*/
|
*/
|
||||||
static void callclosemethod (lua_State *L, TValue *obj, TValue *err, int yy) {
|
static void callclosemethod (lua_State *L, TValue *obj, TValue *err, int yy) {
|
||||||
StkId top = L->top;
|
StkId top = L->top.p;
|
||||||
const TValue *tm = luaT_gettmbyobj(L, obj, TM_CLOSE);
|
const TValue *tm = luaT_gettmbyobj(L, obj, TM_CLOSE);
|
||||||
setobj2s(L, top, tm); /* will call metamethod... */
|
setobj2s(L, top, tm); /* will call metamethod... */
|
||||||
setobj2s(L, top + 1, obj); /* with 'self' as the 1st argument */
|
setobj2s(L, top + 1, obj); /* with 'self' as the 1st argument */
|
||||||
setobj2s(L, top + 2, err); /* and error msg. as 2nd argument */
|
setobj2s(L, top + 2, err); /* and error msg. as 2nd argument */
|
||||||
L->top = top + 3; /* add function and arguments */
|
L->top.p = top + 3; /* add function and arguments */
|
||||||
if (yy)
|
if (yy)
|
||||||
luaD_call(L, top, 0);
|
luaD_call(L, top, 0);
|
||||||
else
|
else
|
||||||
@ -126,7 +126,7 @@ static void callclosemethod (lua_State *L, TValue *obj, TValue *err, int yy) {
|
|||||||
static void checkclosemth (lua_State *L, StkId level) {
|
static void checkclosemth (lua_State *L, StkId level) {
|
||||||
const TValue *tm = luaT_gettmbyobj(L, s2v(level), TM_CLOSE);
|
const TValue *tm = luaT_gettmbyobj(L, s2v(level), TM_CLOSE);
|
||||||
if (ttisnil(tm)) { /* no metamethod? */
|
if (ttisnil(tm)) { /* no metamethod? */
|
||||||
int idx = cast_int(level - L->ci->func); /* variable index */
|
int idx = cast_int(level - L->ci->func.p); /* variable index */
|
||||||
const char *vname = luaG_findlocal(L, L->ci, idx, NULL);
|
const char *vname = luaG_findlocal(L, L->ci, idx, NULL);
|
||||||
if (vname == NULL) vname = "?";
|
if (vname == NULL) vname = "?";
|
||||||
luaG_runerror(L, "variable '%s' got a non-closable value", vname);
|
luaG_runerror(L, "variable '%s' got a non-closable value", vname);
|
||||||
@ -160,23 +160,23 @@ static void prepcallclosemth (lua_State *L, StkId level, int status, int yy) {
|
|||||||
** is used.)
|
** is used.)
|
||||||
*/
|
*/
|
||||||
#define MAXDELTA \
|
#define MAXDELTA \
|
||||||
((256ul << ((sizeof(L->stack->tbclist.delta) - 1) * 8)) - 1)
|
((256ul << ((sizeof(L->stack.p->tbclist.delta) - 1) * 8)) - 1)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Insert a variable in the list of to-be-closed variables.
|
** Insert a variable in the list of to-be-closed variables.
|
||||||
*/
|
*/
|
||||||
void luaF_newtbcupval (lua_State *L, StkId level) {
|
void luaF_newtbcupval (lua_State *L, StkId level) {
|
||||||
lua_assert(level > L->tbclist);
|
lua_assert(level > L->tbclist.p);
|
||||||
if (l_isfalse(s2v(level)))
|
if (l_isfalse(s2v(level)))
|
||||||
return; /* false doesn't need to be closed */
|
return; /* false doesn't need to be closed */
|
||||||
checkclosemth(L, level); /* value must have a close method */
|
checkclosemth(L, level); /* value must have a close method */
|
||||||
while (cast_uint(level - L->tbclist) > MAXDELTA) {
|
while (cast_uint(level - L->tbclist.p) > MAXDELTA) {
|
||||||
L->tbclist += MAXDELTA; /* create a dummy node at maximum delta */
|
L->tbclist.p += MAXDELTA; /* create a dummy node at maximum delta */
|
||||||
L->tbclist->tbclist.delta = 0;
|
L->tbclist.p->tbclist.delta = 0;
|
||||||
}
|
}
|
||||||
level->tbclist.delta = cast(unsigned short, level - L->tbclist);
|
level->tbclist.delta = cast(unsigned short, level - L->tbclist.p);
|
||||||
L->tbclist = level;
|
L->tbclist.p = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -196,10 +196,10 @@ void luaF_closeupval (lua_State *L, StkId level) {
|
|||||||
StkId upl; /* stack index pointed by 'uv' */
|
StkId upl; /* stack index pointed by 'uv' */
|
||||||
while ((uv = L->openupval) != NULL && (upl = uplevel(uv)) >= level) {
|
while ((uv = L->openupval) != NULL && (upl = uplevel(uv)) >= level) {
|
||||||
TValue *slot = &uv->u.value; /* new position for value */
|
TValue *slot = &uv->u.value; /* new position for value */
|
||||||
lua_assert(uplevel(uv) < L->top);
|
lua_assert(uplevel(uv) < L->top.p);
|
||||||
luaF_unlinkupval(uv); /* remove upvalue from 'openupval' list */
|
luaF_unlinkupval(uv); /* remove upvalue from 'openupval' list */
|
||||||
setobj(L, slot, uv->v); /* move value to upvalue slot */
|
setobj(L, slot, uv->v.p); /* move value to upvalue slot */
|
||||||
uv->v = slot; /* now current value lives here */
|
uv->v.p = slot; /* now current value lives here */
|
||||||
if (!iswhite(uv)) { /* neither white nor dead? */
|
if (!iswhite(uv)) { /* neither white nor dead? */
|
||||||
nw2black(uv); /* closed upvalues cannot be gray */
|
nw2black(uv); /* closed upvalues cannot be gray */
|
||||||
luaC_barrier(L, uv, slot);
|
luaC_barrier(L, uv, slot);
|
||||||
@ -212,12 +212,12 @@ void luaF_closeupval (lua_State *L, StkId level) {
|
|||||||
** Remove first element from the tbclist plus its dummy nodes.
|
** Remove first element from the tbclist plus its dummy nodes.
|
||||||
*/
|
*/
|
||||||
static void poptbclist (lua_State *L) {
|
static void poptbclist (lua_State *L) {
|
||||||
StkId tbc = L->tbclist;
|
StkId tbc = L->tbclist.p;
|
||||||
lua_assert(tbc->tbclist.delta > 0); /* first element cannot be dummy */
|
lua_assert(tbc->tbclist.delta > 0); /* first element cannot be dummy */
|
||||||
tbc -= tbc->tbclist.delta;
|
tbc -= tbc->tbclist.delta;
|
||||||
while (tbc > L->stack && tbc->tbclist.delta == 0)
|
while (tbc > L->stack.p && tbc->tbclist.delta == 0)
|
||||||
tbc -= MAXDELTA; /* remove dummy nodes */
|
tbc -= MAXDELTA; /* remove dummy nodes */
|
||||||
L->tbclist = tbc;
|
L->tbclist.p = tbc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -228,8 +228,8 @@ static void poptbclist (lua_State *L) {
|
|||||||
StkId luaF_close (lua_State *L, StkId level, int status, int yy) {
|
StkId luaF_close (lua_State *L, StkId level, int status, int yy) {
|
||||||
ptrdiff_t levelrel = savestack(L, level);
|
ptrdiff_t levelrel = savestack(L, level);
|
||||||
luaF_closeupval(L, level); /* first, close the upvalues */
|
luaF_closeupval(L, level); /* first, close the upvalues */
|
||||||
while (L->tbclist >= level) { /* traverse tbc's down to that level */
|
while (L->tbclist.p >= level) { /* traverse tbc's down to that level */
|
||||||
StkId tbc = L->tbclist; /* get variable index */
|
StkId tbc = L->tbclist.p; /* get variable index */
|
||||||
poptbclist(L); /* remove it from list */
|
poptbclist(L); /* remove it from list */
|
||||||
prepcallclosemth(L, tbc, status, yy); /* close variable */
|
prepcallclosemth(L, tbc, status, yy); /* close variable */
|
||||||
level = restorestack(L, levelrel);
|
level = restorestack(L, levelrel);
|
||||||
|
4
lfunc.h
4
lfunc.h
@ -29,10 +29,10 @@
|
|||||||
#define MAXUPVAL 255
|
#define MAXUPVAL 255
|
||||||
|
|
||||||
|
|
||||||
#define upisopen(up) ((up)->v != &(up)->u.value)
|
#define upisopen(up) ((up)->v.p != &(up)->u.value)
|
||||||
|
|
||||||
|
|
||||||
#define uplevel(up) check_exp(upisopen(up), cast(StkId, (up)->v))
|
#define uplevel(up) check_exp(upisopen(up), cast(StkId, (up)->v.p))
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
20
lgc.c
20
lgc.c
@ -301,7 +301,7 @@ static void reallymarkobject (global_State *g, GCObject *o) {
|
|||||||
set2gray(uv); /* open upvalues are kept gray */
|
set2gray(uv); /* open upvalues are kept gray */
|
||||||
else
|
else
|
||||||
set2black(uv); /* closed upvalues are visited here */
|
set2black(uv); /* closed upvalues are visited here */
|
||||||
markvalue(g, uv->v); /* mark its content */
|
markvalue(g, uv->v.p); /* mark its content */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LUA_VUSERDATA: {
|
case LUA_VUSERDATA: {
|
||||||
@ -376,7 +376,7 @@ static int remarkupvals (global_State *g) {
|
|||||||
work++;
|
work++;
|
||||||
if (!iswhite(uv)) { /* upvalue already visited? */
|
if (!iswhite(uv)) { /* upvalue already visited? */
|
||||||
lua_assert(upisopen(uv) && isgray(uv));
|
lua_assert(upisopen(uv) && isgray(uv));
|
||||||
markvalue(g, uv->v); /* mark its value */
|
markvalue(g, uv->v.p); /* mark its value */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -620,19 +620,19 @@ static int traverseLclosure (global_State *g, LClosure *cl) {
|
|||||||
*/
|
*/
|
||||||
static int traversethread (global_State *g, lua_State *th) {
|
static int traversethread (global_State *g, lua_State *th) {
|
||||||
UpVal *uv;
|
UpVal *uv;
|
||||||
StkId o = th->stack;
|
StkId o = th->stack.p;
|
||||||
if (isold(th) || g->gcstate == GCSpropagate)
|
if (isold(th) || g->gcstate == GCSpropagate)
|
||||||
linkgclist(th, g->grayagain); /* insert into 'grayagain' list */
|
linkgclist(th, g->grayagain); /* insert into 'grayagain' list */
|
||||||
if (o == NULL)
|
if (o == NULL)
|
||||||
return 1; /* stack not completely built yet */
|
return 1; /* stack not completely built yet */
|
||||||
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.p; o++) /* mark live elements in the stack */
|
||||||
markvalue(g, s2v(o));
|
markvalue(g, s2v(o));
|
||||||
for (uv = th->openupval; uv != NULL; uv = uv->u.open.next)
|
for (uv = th->openupval; uv != NULL; uv = uv->u.open.next)
|
||||||
markobject(g, uv); /* open upvalues cannot be collected */
|
markobject(g, uv); /* open upvalues cannot be collected */
|
||||||
if (g->gcstate == GCSatomic) { /* final traversal? */
|
if (g->gcstate == GCSatomic) { /* final traversal? */
|
||||||
for (; o < th->stack_last + EXTRA_STACK; o++)
|
for (; o < th->stack_last.p + EXTRA_STACK; o++)
|
||||||
setnilvalue(s2v(o)); /* clear dead stack slice */
|
setnilvalue(s2v(o)); /* clear dead stack slice */
|
||||||
/* '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) {
|
||||||
@ -892,7 +892,7 @@ static GCObject *udata2finalize (global_State *g) {
|
|||||||
|
|
||||||
static void dothecall (lua_State *L, void *ud) {
|
static void dothecall (lua_State *L, void *ud) {
|
||||||
UNUSED(ud);
|
UNUSED(ud);
|
||||||
luaD_callnoyield(L, L->top - 2, 0);
|
luaD_callnoyield(L, L->top.p - 2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -909,16 +909,16 @@ static void GCTM (lua_State *L) {
|
|||||||
int oldgcstp = g->gcstp;
|
int oldgcstp = g->gcstp;
|
||||||
g->gcstp |= GCSTPGC; /* avoid GC steps */
|
g->gcstp |= GCSTPGC; /* avoid GC steps */
|
||||||
L->allowhook = 0; /* stop debug hooks during GC metamethod */
|
L->allowhook = 0; /* stop debug hooks during GC metamethod */
|
||||||
setobj2s(L, L->top++, tm); /* push finalizer... */
|
setobj2s(L, L->top.p++, tm); /* push finalizer... */
|
||||||
setobj2s(L, L->top++, &v); /* ... and its argument */
|
setobj2s(L, L->top.p++, &v); /* ... and its argument */
|
||||||
L->ci->callstatus |= CIST_FIN; /* will run a finalizer */
|
L->ci->callstatus |= CIST_FIN; /* will run a finalizer */
|
||||||
status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0);
|
status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top.p - 2), 0);
|
||||||
L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */
|
L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */
|
||||||
L->allowhook = oldah; /* restore hooks */
|
L->allowhook = oldah; /* restore hooks */
|
||||||
g->gcstp = oldgcstp; /* restore state */
|
g->gcstp = oldgcstp; /* restore state */
|
||||||
if (l_unlikely(status != LUA_OK)) { /* error while running __gc? */
|
if (l_unlikely(status != LUA_OK)) { /* error while running __gc? */
|
||||||
luaE_warnerror(L, "__gc");
|
luaE_warnerror(L, "__gc");
|
||||||
L->top--; /* pops error object */
|
L->top.p--; /* pops error object */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
4
llex.c
4
llex.c
@ -138,12 +138,12 @@ TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
|
|||||||
if (!ttisnil(o)) /* string already present? */
|
if (!ttisnil(o)) /* string already present? */
|
||||||
ts = keystrval(nodefromval(o)); /* get saved copy */
|
ts = keystrval(nodefromval(o)); /* get saved copy */
|
||||||
else { /* not in use yet */
|
else { /* not in use yet */
|
||||||
TValue *stv = s2v(L->top++); /* reserve stack space for string */
|
TValue *stv = s2v(L->top.p++); /* reserve stack space for string */
|
||||||
setsvalue(L, stv, ts); /* temporarily anchor the string */
|
setsvalue(L, stv, ts); /* temporarily anchor the string */
|
||||||
luaH_finishset(L, ls->h, stv, o, stv); /* t[string] = string */
|
luaH_finishset(L, ls->h, stv, o, stv); /* t[string] = string */
|
||||||
/* 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 */
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
L->top--; /* remove string from stack */
|
L->top.p--; /* remove string from stack */
|
||||||
}
|
}
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
@ -413,8 +413,8 @@ typedef struct BuffFS {
|
|||||||
*/
|
*/
|
||||||
static void pushstr (BuffFS *buff, const char *str, size_t lstr) {
|
static void pushstr (BuffFS *buff, const char *str, size_t lstr) {
|
||||||
lua_State *L = buff->L;
|
lua_State *L = buff->L;
|
||||||
setsvalue2s(L, L->top, luaS_newlstr(L, str, lstr));
|
setsvalue2s(L, L->top.p, luaS_newlstr(L, str, lstr));
|
||||||
L->top++; /* may use one slot from EXTRA_STACK */
|
L->top.p++; /* may use one slot from EXTRA_STACK */
|
||||||
if (!buff->pushed) /* no previous string on the stack? */
|
if (!buff->pushed) /* no previous string on the stack? */
|
||||||
buff->pushed = 1; /* now there is one */
|
buff->pushed = 1; /* now there is one */
|
||||||
else /* join previous string with new one */
|
else /* join previous string with new one */
|
||||||
@ -542,7 +542,7 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
|
|||||||
addstr2buff(&buff, fmt, strlen(fmt)); /* rest of 'fmt' */
|
addstr2buff(&buff, fmt, strlen(fmt)); /* rest of 'fmt' */
|
||||||
clearbuff(&buff); /* empty buffer into the stack */
|
clearbuff(&buff); /* empty buffer into the stack */
|
||||||
lua_assert(buff.pushed == 1);
|
lua_assert(buff.pushed == 1);
|
||||||
return svalue(s2v(L->top - 1));
|
return svalue(s2v(L->top.p - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
10
lobject.h
10
lobject.h
@ -157,6 +157,12 @@ typedef union StackValue {
|
|||||||
/* index to stack elements */
|
/* index to stack elements */
|
||||||
typedef StackValue *StkId;
|
typedef StackValue *StkId;
|
||||||
|
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
StkId p; /* actual pointer */
|
||||||
|
} StkIdRel;
|
||||||
|
|
||||||
|
|
||||||
/* convert a 'StackValue' to a 'TValue' */
|
/* convert a 'StackValue' to a 'TValue' */
|
||||||
#define s2v(o) (&(o)->val)
|
#define s2v(o) (&(o)->val)
|
||||||
|
|
||||||
@ -618,7 +624,9 @@ typedef struct Proto {
|
|||||||
typedef struct UpVal {
|
typedef struct UpVal {
|
||||||
CommonHeader;
|
CommonHeader;
|
||||||
lu_byte tbc; /* true if it represents a to-be-closed variable */
|
lu_byte tbc; /* true if it represents a to-be-closed variable */
|
||||||
TValue *v; /* points to stack or to its own value */
|
union {
|
||||||
|
TValue *p; /* points to stack or to its own value */
|
||||||
|
} v;
|
||||||
union {
|
union {
|
||||||
struct { /* (when open) */
|
struct { /* (when open) */
|
||||||
struct UpVal *next; /* linked list */
|
struct UpVal *next; /* linked list */
|
||||||
|
@ -1944,10 +1944,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 */
|
||||||
setclLvalue2s(L, L->top, cl); /* anchor it (to avoid being collected) */
|
setclLvalue2s(L, L->top.p, 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 */
|
||||||
sethvalue2s(L, L->top, lexstate.h); /* anchor it */
|
sethvalue2s(L, L->top.p, lexstate.h); /* anchor it */
|
||||||
luaD_inctop(L);
|
luaD_inctop(L);
|
||||||
funcstate.f = cl->p = luaF_newproto(L);
|
funcstate.f = cl->p = luaF_newproto(L);
|
||||||
luaC_objbarrier(L, cl, cl->p);
|
luaC_objbarrier(L, cl, cl->p);
|
||||||
@ -1961,7 +1961,7 @@ LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
|
|||||||
lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);
|
lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);
|
||||||
/* all scopes should be correctly finished */
|
/* all scopes should be correctly finished */
|
||||||
lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0);
|
lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0);
|
||||||
L->top--; /* remove scanner's table */
|
L->top.p--; /* remove scanner's table */
|
||||||
return cl; /* closure is on the stack, too */
|
return cl; /* closure is on the stack, too */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
42
lstate.c
42
lstate.c
@ -180,33 +180,33 @@ LUAI_FUNC void luaE_incCstack (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 + EXTRA_STACK, StackValue);
|
L1->stack.p = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, StackValue);
|
||||||
L1->tbclist = L1->stack;
|
L1->tbclist.p = L1->stack.p;
|
||||||
for (i = 0; i < BASIC_STACK_SIZE + EXTRA_STACK; i++)
|
for (i = 0; i < BASIC_STACK_SIZE + EXTRA_STACK; i++)
|
||||||
setnilvalue(s2v(L1->stack + i)); /* erase new stack */
|
setnilvalue(s2v(L1->stack.p + i)); /* erase new stack */
|
||||||
L1->top = L1->stack;
|
L1->top.p = L1->stack.p;
|
||||||
L1->stack_last = L1->stack + BASIC_STACK_SIZE;
|
L1->stack_last.p = L1->stack.p + BASIC_STACK_SIZE;
|
||||||
/* initialize first ci */
|
/* initialize first ci */
|
||||||
ci = &L1->base_ci;
|
ci = &L1->base_ci;
|
||||||
ci->next = ci->previous = NULL;
|
ci->next = ci->previous = NULL;
|
||||||
ci->callstatus = CIST_C;
|
ci->callstatus = CIST_C;
|
||||||
ci->func = L1->top;
|
ci->func.p = L1->top.p;
|
||||||
ci->u.c.k = NULL;
|
ci->u.c.k = NULL;
|
||||||
ci->nresults = 0;
|
ci->nresults = 0;
|
||||||
setnilvalue(s2v(L1->top)); /* 'function' entry for this 'ci' */
|
setnilvalue(s2v(L1->top.p)); /* 'function' entry for this 'ci' */
|
||||||
L1->top++;
|
L1->top.p++;
|
||||||
ci->top = L1->top + LUA_MINSTACK;
|
ci->top.p = L1->top.p + LUA_MINSTACK;
|
||||||
L1->ci = ci;
|
L1->ci = ci;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void freestack (lua_State *L) {
|
static void freestack (lua_State *L) {
|
||||||
if (L->stack == NULL)
|
if (L->stack.p == NULL)
|
||||||
return; /* stack not completely built yet */
|
return; /* stack not completely built yet */
|
||||||
L->ci = &L->base_ci; /* free the entire 'ci' list */
|
L->ci = &L->base_ci; /* free the entire 'ci' list */
|
||||||
luaE_freeCI(L);
|
luaE_freeCI(L);
|
||||||
lua_assert(L->nci == 0);
|
lua_assert(L->nci == 0);
|
||||||
luaM_freearray(L, L->stack, stacksize(L) + EXTRA_STACK); /* free stack */
|
luaM_freearray(L, L->stack.p, stacksize(L) + EXTRA_STACK); /* free stack */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -248,7 +248,7 @@ static void f_luaopen (lua_State *L, void *ud) {
|
|||||||
*/
|
*/
|
||||||
static void preinit_thread (lua_State *L, global_State *g) {
|
static void preinit_thread (lua_State *L, global_State *g) {
|
||||||
G(L) = g;
|
G(L) = g;
|
||||||
L->stack = NULL;
|
L->stack.p = NULL;
|
||||||
L->ci = NULL;
|
L->ci = NULL;
|
||||||
L->nci = 0;
|
L->nci = 0;
|
||||||
L->twups = L; /* thread has no upvalues */
|
L->twups = L; /* thread has no upvalues */
|
||||||
@ -297,7 +297,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 */
|
||||||
setthvalue2s(L, L->top, L1);
|
setthvalue2s(L, L->top.p, 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;
|
||||||
@ -316,7 +316,7 @@ LUA_API lua_State *lua_newthread (lua_State *L) {
|
|||||||
|
|
||||||
void luaE_freethread (lua_State *L, lua_State *L1) {
|
void luaE_freethread (lua_State *L, lua_State *L1) {
|
||||||
LX *l = fromstate(L1);
|
LX *l = fromstate(L1);
|
||||||
luaF_closeupval(L1, L1->stack); /* close all upvalues */
|
luaF_closeupval(L1, L1->stack.p); /* close all upvalues */
|
||||||
lua_assert(L1->openupval == NULL);
|
lua_assert(L1->openupval == NULL);
|
||||||
luai_userstatefree(L, L1);
|
luai_userstatefree(L, L1);
|
||||||
freestack(L1);
|
freestack(L1);
|
||||||
@ -326,19 +326,19 @@ void luaE_freethread (lua_State *L, lua_State *L1) {
|
|||||||
|
|
||||||
int luaE_resetthread (lua_State *L, int status) {
|
int luaE_resetthread (lua_State *L, int status) {
|
||||||
CallInfo *ci = L->ci = &L->base_ci; /* unwind CallInfo list */
|
CallInfo *ci = L->ci = &L->base_ci; /* unwind CallInfo list */
|
||||||
setnilvalue(s2v(L->stack)); /* 'function' entry for basic 'ci' */
|
setnilvalue(s2v(L->stack.p)); /* 'function' entry for basic 'ci' */
|
||||||
ci->func = L->stack;
|
ci->func.p = L->stack.p;
|
||||||
ci->callstatus = CIST_C;
|
ci->callstatus = CIST_C;
|
||||||
if (status == LUA_YIELD)
|
if (status == LUA_YIELD)
|
||||||
status = LUA_OK;
|
status = LUA_OK;
|
||||||
L->status = LUA_OK; /* so it can run __close metamethods */
|
L->status = LUA_OK; /* so it can run __close metamethods */
|
||||||
status = luaD_closeprotected(L, 1, status);
|
status = luaD_closeprotected(L, 1, status);
|
||||||
if (status != LUA_OK) /* errors? */
|
if (status != LUA_OK) /* errors? */
|
||||||
luaD_seterrorobj(L, status, L->stack + 1);
|
luaD_seterrorobj(L, status, L->stack.p + 1);
|
||||||
else
|
else
|
||||||
L->top = L->stack + 1;
|
L->top.p = L->stack.p + 1;
|
||||||
ci->top = L->top + LUA_MINSTACK;
|
ci->top.p = L->top.p + LUA_MINSTACK;
|
||||||
luaD_reallocstack(L, cast_int(ci->top - L->stack), 0);
|
luaD_reallocstack(L, cast_int(ci->top.p - L->stack.p), 0);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -427,7 +427,7 @@ void luaE_warning (lua_State *L, const char *msg, int tocont) {
|
|||||||
** Generate a warning from an error message
|
** Generate a warning from an error message
|
||||||
*/
|
*/
|
||||||
void luaE_warnerror (lua_State *L, const char *where) {
|
void luaE_warnerror (lua_State *L, const char *where) {
|
||||||
TValue *errobj = s2v(L->top - 1); /* error object */
|
TValue *errobj = s2v(L->top.p - 1); /* error object */
|
||||||
const char *msg = (ttisstring(errobj))
|
const char *msg = (ttisstring(errobj))
|
||||||
? svalue(errobj)
|
? svalue(errobj)
|
||||||
: "error object is not a string";
|
: "error object is not a string";
|
||||||
|
14
lstate.h
14
lstate.h
@ -139,7 +139,7 @@ struct lua_longjmp; /* defined in ldo.c */
|
|||||||
|
|
||||||
#define BASIC_STACK_SIZE (2*LUA_MINSTACK)
|
#define BASIC_STACK_SIZE (2*LUA_MINSTACK)
|
||||||
|
|
||||||
#define stacksize(th) cast_int((th)->stack_last - (th)->stack)
|
#define stacksize(th) cast_int((th)->stack_last.p - (th)->stack.p)
|
||||||
|
|
||||||
|
|
||||||
/* kinds of Garbage Collection */
|
/* kinds of Garbage Collection */
|
||||||
@ -170,8 +170,8 @@ typedef struct stringtable {
|
|||||||
** before the function starts or after it ends.
|
** before the function starts or after it ends.
|
||||||
*/
|
*/
|
||||||
typedef struct CallInfo {
|
typedef struct CallInfo {
|
||||||
StkId func; /* function index in the stack */
|
StkIdRel func; /* function index in the stack */
|
||||||
StkId top; /* top for this function */
|
StkIdRel top; /* top for this function */
|
||||||
struct CallInfo *previous, *next; /* dynamic call link */
|
struct CallInfo *previous, *next; /* dynamic call link */
|
||||||
union {
|
union {
|
||||||
struct { /* only for Lua functions */
|
struct { /* only for Lua functions */
|
||||||
@ -306,13 +306,13 @@ struct lua_State {
|
|||||||
lu_byte status;
|
lu_byte status;
|
||||||
lu_byte allowhook;
|
lu_byte allowhook;
|
||||||
unsigned short nci; /* number of items in 'ci' list */
|
unsigned short nci; /* number of items in 'ci' list */
|
||||||
StkId top; /* first free slot in the stack */
|
StkIdRel top; /* first free slot in the stack */
|
||||||
global_State *l_G;
|
global_State *l_G;
|
||||||
CallInfo *ci; /* call info for current function */
|
CallInfo *ci; /* call info for current function */
|
||||||
StkId stack_last; /* end of stack (last element + 1) */
|
StkIdRel stack_last; /* end of stack (last element + 1) */
|
||||||
StkId stack; /* stack base */
|
StkIdRel stack; /* stack base */
|
||||||
UpVal *openupval; /* list of open upvalues in this stack */
|
UpVal *openupval; /* list of open upvalues in this stack */
|
||||||
StkId tbclist; /* list of to-be-closed variables */
|
StkIdRel tbclist; /* list of to-be-closed variables */
|
||||||
GCObject *gclist;
|
GCObject *gclist;
|
||||||
struct lua_State *twups; /* list of threads with open upvalues */
|
struct lua_State *twups; /* list of threads with open upvalues */
|
||||||
struct lua_longjmp *errorJmp; /* current error recover point */
|
struct lua_longjmp *errorJmp; /* current error recover point */
|
||||||
|
24
ltests.c
24
ltests.c
@ -44,7 +44,7 @@
|
|||||||
void *l_Trick = 0;
|
void *l_Trick = 0;
|
||||||
|
|
||||||
|
|
||||||
#define obj_at(L,k) s2v(L->ci->func + (k))
|
#define obj_at(L,k) s2v(L->ci->func.p + (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);
|
||||||
@ -57,7 +57,7 @@ static void setnameval (lua_State *L, const char *name, int val) {
|
|||||||
|
|
||||||
|
|
||||||
static void pushobject (lua_State *L, const TValue *o) {
|
static void pushobject (lua_State *L, const TValue *o) {
|
||||||
setobj2s(L, L->top, o);
|
setobj2s(L, L->top.p, o);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -419,7 +419,7 @@ static void checkLclosure (global_State *g, LClosure *cl) {
|
|||||||
if (uv) {
|
if (uv) {
|
||||||
checkobjrefN(g, clgc, uv);
|
checkobjrefN(g, clgc, uv);
|
||||||
if (!upisopen(uv))
|
if (!upisopen(uv))
|
||||||
checkvalref(g, obj2gco(uv), uv->v);
|
checkvalref(g, obj2gco(uv), uv->v.p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -428,7 +428,7 @@ static void checkLclosure (global_State *g, LClosure *cl) {
|
|||||||
static int lua_checkpc (CallInfo *ci) {
|
static int lua_checkpc (CallInfo *ci) {
|
||||||
if (!isLua(ci)) return 1;
|
if (!isLua(ci)) return 1;
|
||||||
else {
|
else {
|
||||||
StkId f = ci->func;
|
StkId f = ci->func.p;
|
||||||
Proto *p = clLvalue(s2v(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;
|
||||||
@ -441,19 +441,19 @@ static void checkstack (global_State *g, lua_State *L1) {
|
|||||||
CallInfo *ci;
|
CallInfo *ci;
|
||||||
UpVal *uv;
|
UpVal *uv;
|
||||||
assert(!isdead(g, L1));
|
assert(!isdead(g, L1));
|
||||||
if (L1->stack == NULL) { /* incomplete thread? */
|
if (L1->stack.p == NULL) { /* incomplete thread? */
|
||||||
assert(L1->openupval == NULL && L1->ci == NULL);
|
assert(L1->openupval == NULL && L1->ci == NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (uv = L1->openupval; uv != NULL; uv = uv->u.open.next)
|
for (uv = L1->openupval; uv != NULL; uv = uv->u.open.next)
|
||||||
assert(upisopen(uv)); /* must be open */
|
assert(upisopen(uv)); /* must be open */
|
||||||
assert(L1->top <= L1->stack_last);
|
assert(L1->top.p <= L1->stack_last.p);
|
||||||
assert(L1->tbclist <= L1->top);
|
assert(L1->tbclist.p <= L1->top.p);
|
||||||
for (ci = L1->ci; ci != NULL; ci = ci->previous) {
|
for (ci = L1->ci; ci != NULL; ci = ci->previous) {
|
||||||
assert(ci->top <= L1->stack_last);
|
assert(ci->top.p <= L1->stack_last.p);
|
||||||
assert(lua_checkpc(ci));
|
assert(lua_checkpc(ci));
|
||||||
}
|
}
|
||||||
for (o = L1->stack; o < L1->stack_last; o++)
|
for (o = L1->stack.p; o < L1->stack_last.p; o++)
|
||||||
checkliveness(L1, s2v(o)); /* entire stack must have valid values */
|
checkliveness(L1, s2v(o)); /* entire stack must have valid values */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,7 +465,7 @@ static void checkrefs (global_State *g, GCObject *o) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LUA_VUPVAL: {
|
case LUA_VUPVAL: {
|
||||||
checkvalref(g, o, gco2upv(o)->v);
|
checkvalref(g, o, gco2upv(o)->v.p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LUA_VTABLE: {
|
case LUA_VTABLE: {
|
||||||
@ -980,7 +980,7 @@ static int hash_query (lua_State *L) {
|
|||||||
|
|
||||||
static int stacklevel (lua_State *L) {
|
static int stacklevel (lua_State *L) {
|
||||||
unsigned long a = 0;
|
unsigned long a = 0;
|
||||||
lua_pushinteger(L, (L->top - L->stack));
|
lua_pushinteger(L, (L->top.p - L->stack.p));
|
||||||
lua_pushinteger(L, stacksize(L));
|
lua_pushinteger(L, stacksize(L));
|
||||||
lua_pushinteger(L, L->nCcalls);
|
lua_pushinteger(L, L->nCcalls);
|
||||||
lua_pushinteger(L, L->nci);
|
lua_pushinteger(L, L->nci);
|
||||||
@ -1040,7 +1040,7 @@ static int string_query (lua_State *L) {
|
|||||||
TString *ts;
|
TString *ts;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
for (ts = tb->hash[s]; ts != NULL; ts = ts->u.hnext) {
|
for (ts = tb->hash[s]; ts != NULL; ts = ts->u.hnext) {
|
||||||
setsvalue2s(L, L->top, ts);
|
setsvalue2s(L, L->top.p, ts);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
|
38
ltm.c
38
ltm.c
@ -102,12 +102,12 @@ 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, const TValue *p3) {
|
const TValue *p2, const TValue *p3) {
|
||||||
StkId func = L->top;
|
StkId func = L->top.p;
|
||||||
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 */
|
||||||
setobj2s(L, func + 3, p3); /* 3rd argument */
|
setobj2s(L, func + 3, p3); /* 3rd argument */
|
||||||
L->top = func + 4;
|
L->top.p = func + 4;
|
||||||
/* metamethod may yield only when called from Lua code */
|
/* metamethod may yield only when called from Lua code */
|
||||||
if (isLuacode(L->ci))
|
if (isLuacode(L->ci))
|
||||||
luaD_call(L, func, 0);
|
luaD_call(L, func, 0);
|
||||||
@ -119,18 +119,18 @@ void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
|
|||||||
void luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1,
|
void luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1,
|
||||||
const TValue *p2, StkId res) {
|
const TValue *p2, StkId res) {
|
||||||
ptrdiff_t result = savestack(L, res);
|
ptrdiff_t result = savestack(L, res);
|
||||||
StkId func = L->top;
|
StkId func = L->top.p;
|
||||||
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.p += 3;
|
||||||
/* metamethod may yield only when called from Lua code */
|
/* metamethod may yield only when called from Lua code */
|
||||||
if (isLuacode(L->ci))
|
if (isLuacode(L->ci))
|
||||||
luaD_call(L, func, 1);
|
luaD_call(L, func, 1);
|
||||||
else
|
else
|
||||||
luaD_callnoyield(L, func, 1);
|
luaD_callnoyield(L, func, 1);
|
||||||
res = restorestack(L, result);
|
res = restorestack(L, result);
|
||||||
setobjs2s(L, res, --L->top); /* move result to its place */
|
setobjs2s(L, res, --L->top.p); /* move result to its place */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -165,7 +165,7 @@ void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
|
|||||||
|
|
||||||
|
|
||||||
void luaT_tryconcatTM (lua_State *L) {
|
void luaT_tryconcatTM (lua_State *L) {
|
||||||
StkId top = L->top;
|
StkId top = L->top.p;
|
||||||
if (l_unlikely(!callbinTM(L, s2v(top - 2), s2v(top - 1), top - 2,
|
if (l_unlikely(!callbinTM(L, s2v(top - 2), s2v(top - 1), top - 2,
|
||||||
TM_CONCAT)))
|
TM_CONCAT)))
|
||||||
luaG_concaterror(L, s2v(top - 2), s2v(top - 1));
|
luaG_concaterror(L, s2v(top - 2), s2v(top - 1));
|
||||||
@ -200,15 +200,15 @@ void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2,
|
|||||||
*/
|
*/
|
||||||
int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2,
|
int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2,
|
||||||
TMS event) {
|
TMS event) {
|
||||||
if (callbinTM(L, p1, p2, L->top, event)) /* try original event */
|
if (callbinTM(L, p1, p2, L->top.p, event)) /* try original event */
|
||||||
return !l_isfalse(s2v(L->top));
|
return !l_isfalse(s2v(L->top.p));
|
||||||
#if defined(LUA_COMPAT_LT_LE)
|
#if defined(LUA_COMPAT_LT_LE)
|
||||||
else if (event == TM_LE) {
|
else if (event == TM_LE) {
|
||||||
/* try '!(p2 < p1)' for '(p1 <= p2)' */
|
/* try '!(p2 < p1)' for '(p1 <= p2)' */
|
||||||
L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */
|
L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */
|
||||||
if (callbinTM(L, p2, p1, L->top, TM_LT)) {
|
if (callbinTM(L, p2, p1, L->top.p, TM_LT)) {
|
||||||
L->ci->callstatus ^= CIST_LEQ; /* clear mark */
|
L->ci->callstatus ^= CIST_LEQ; /* clear mark */
|
||||||
return l_isfalse(s2v(L->top));
|
return l_isfalse(s2v(L->top.p));
|
||||||
}
|
}
|
||||||
/* else error will remove this 'ci'; no need to clear mark */
|
/* else error will remove this 'ci'; no need to clear mark */
|
||||||
}
|
}
|
||||||
@ -238,20 +238,20 @@ int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2,
|
|||||||
void luaT_adjustvarargs (lua_State *L, int nfixparams, CallInfo *ci,
|
void luaT_adjustvarargs (lua_State *L, int nfixparams, CallInfo *ci,
|
||||||
const Proto *p) {
|
const Proto *p) {
|
||||||
int i;
|
int i;
|
||||||
int actual = cast_int(L->top - ci->func) - 1; /* number of arguments */
|
int actual = cast_int(L->top.p - ci->func.p) - 1; /* number of arguments */
|
||||||
int nextra = actual - nfixparams; /* number of extra arguments */
|
int nextra = actual - nfixparams; /* number of extra arguments */
|
||||||
ci->u.l.nextraargs = nextra;
|
ci->u.l.nextraargs = nextra;
|
||||||
luaD_checkstack(L, p->maxstacksize + 1);
|
luaD_checkstack(L, p->maxstacksize + 1);
|
||||||
/* copy function to the top of the stack */
|
/* copy function to the top of the stack */
|
||||||
setobjs2s(L, L->top++, ci->func);
|
setobjs2s(L, L->top.p++, ci->func.p);
|
||||||
/* move fixed parameters to the top of the stack */
|
/* move fixed parameters to the top of the stack */
|
||||||
for (i = 1; i <= nfixparams; i++) {
|
for (i = 1; i <= nfixparams; i++) {
|
||||||
setobjs2s(L, L->top++, ci->func + i);
|
setobjs2s(L, L->top.p++, ci->func.p + i);
|
||||||
setnilvalue(s2v(ci->func + i)); /* erase original parameter (for GC) */
|
setnilvalue(s2v(ci->func.p + i)); /* erase original parameter (for GC) */
|
||||||
}
|
}
|
||||||
ci->func += actual + 1;
|
ci->func.p += actual + 1;
|
||||||
ci->top += actual + 1;
|
ci->top.p += actual + 1;
|
||||||
lua_assert(L->top <= ci->top && ci->top <= L->stack_last);
|
lua_assert(L->top.p <= ci->top.p && ci->top.p <= L->stack_last.p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -261,10 +261,10 @@ void luaT_getvarargs (lua_State *L, CallInfo *ci, StkId where, int wanted) {
|
|||||||
if (wanted < 0) {
|
if (wanted < 0) {
|
||||||
wanted = nextra; /* get all extra arguments available */
|
wanted = nextra; /* get all extra arguments available */
|
||||||
checkstackGCp(L, nextra, where); /* ensure stack space */
|
checkstackGCp(L, nextra, where); /* ensure stack space */
|
||||||
L->top = where + nextra; /* next instruction will need top */
|
L->top.p = where + nextra; /* next instruction will need top */
|
||||||
}
|
}
|
||||||
for (i = 0; i < wanted && i < nextra; i++)
|
for (i = 0; i < wanted && i < nextra; i++)
|
||||||
setobjs2s(L, where + i, ci->func - nextra + i);
|
setobjs2s(L, where + i, ci->func.p - nextra + i);
|
||||||
for (; i < wanted; i++) /* complete required results with nil */
|
for (; i < wanted; i++) /* complete required results with nil */
|
||||||
setnilvalue(s2v(where + i));
|
setnilvalue(s2v(where + i));
|
||||||
}
|
}
|
||||||
|
@ -120,10 +120,10 @@ static TString *loadStringN (LoadState *S, Proto *p) {
|
|||||||
}
|
}
|
||||||
else { /* long string */
|
else { /* long string */
|
||||||
ts = luaS_createlngstrobj(L, size); /* create string */
|
ts = luaS_createlngstrobj(L, size); /* create string */
|
||||||
setsvalue2s(L, L->top, ts); /* anchor it ('loadVector' can GC) */
|
setsvalue2s(L, L->top.p, ts); /* anchor it ('loadVector' can GC) */
|
||||||
luaD_inctop(L);
|
luaD_inctop(L);
|
||||||
loadVector(S, getstr(ts), size); /* load directly in final place */
|
loadVector(S, getstr(ts), size); /* load directly in final place */
|
||||||
L->top--; /* pop string */
|
L->top.p--; /* pop string */
|
||||||
}
|
}
|
||||||
luaC_objbarrier(L, p, ts);
|
luaC_objbarrier(L, p, ts);
|
||||||
return ts;
|
return ts;
|
||||||
@ -321,7 +321,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));
|
||||||
setclLvalue2s(L, L->top, cl);
|
setclLvalue2s(L, L->top.p, cl);
|
||||||
luaD_inctop(L);
|
luaD_inctop(L);
|
||||||
cl->p = luaF_newproto(L);
|
cl->p = luaF_newproto(L);
|
||||||
luaC_objbarrier(L, cl, cl->p);
|
luaC_objbarrier(L, cl, cl->p);
|
||||||
|
100
lvm.c
100
lvm.c
@ -608,8 +608,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 */
|
||||||
else {
|
else {
|
||||||
luaT_callTMres(L, tm, t1, t2, L->top); /* call TM */
|
luaT_callTMres(L, tm, t1, t2, L->top.p); /* call TM */
|
||||||
return !l_isfalse(s2v(L->top));
|
return !l_isfalse(s2v(L->top.p));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -633,13 +633,13 @@ static void copy2buff (StkId top, int n, char *buff) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** Main operation for concatenation: concat 'total' values in the stack,
|
** Main operation for concatenation: concat 'total' values in the stack,
|
||||||
** from 'L->top - total' up to 'L->top - 1'.
|
** from 'L->top.p - total' up to 'L->top.p - 1'.
|
||||||
*/
|
*/
|
||||||
void luaV_concat (lua_State *L, int total) {
|
void luaV_concat (lua_State *L, int total) {
|
||||||
if (total == 1)
|
if (total == 1)
|
||||||
return; /* "all" values already concatenated */
|
return; /* "all" values already concatenated */
|
||||||
do {
|
do {
|
||||||
StkId top = L->top;
|
StkId top = L->top.p;
|
||||||
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(s2v(top - 2)) || cvt2str(s2v(top - 2))) ||
|
if (!(ttisstring(s2v(top - 2)) || cvt2str(s2v(top - 2))) ||
|
||||||
!tostring(L, s2v(top - 1)))
|
!tostring(L, s2v(top - 1)))
|
||||||
@ -657,7 +657,7 @@ void luaV_concat (lua_State *L, int total) {
|
|||||||
for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) {
|
for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) {
|
||||||
size_t l = vslen(s2v(top - n - 1));
|
size_t l = vslen(s2v(top - n - 1));
|
||||||
if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) {
|
if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) {
|
||||||
L->top = top - total; /* pop strings to avoid wasting stack */
|
L->top.p = top - total; /* pop strings to avoid wasting stack */
|
||||||
luaG_runerror(L, "string length overflow");
|
luaG_runerror(L, "string length overflow");
|
||||||
}
|
}
|
||||||
tl += l;
|
tl += l;
|
||||||
@ -674,7 +674,7 @@ void luaV_concat (lua_State *L, int total) {
|
|||||||
setsvalue2s(L, top - n, ts); /* create result */
|
setsvalue2s(L, top - n, ts); /* create result */
|
||||||
}
|
}
|
||||||
total -= n - 1; /* got 'n' strings to create one new */
|
total -= n - 1; /* got 'n' strings to create one new */
|
||||||
L->top -= n - 1; /* popped 'n' strings and pushed one */
|
L->top.p -= n - 1; /* popped 'n' strings and pushed one */
|
||||||
} while (total > 1); /* repeat until only 1 result left */
|
} while (total > 1); /* repeat until only 1 result left */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -808,26 +808,26 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
|
|||||||
*/
|
*/
|
||||||
void luaV_finishOp (lua_State *L) {
|
void luaV_finishOp (lua_State *L) {
|
||||||
CallInfo *ci = L->ci;
|
CallInfo *ci = L->ci;
|
||||||
StkId base = ci->func + 1;
|
StkId base = ci->func.p + 1;
|
||||||
Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */
|
Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */
|
||||||
OpCode op = GET_OPCODE(inst);
|
OpCode op = GET_OPCODE(inst);
|
||||||
switch (op) { /* finish its execution */
|
switch (op) { /* finish its execution */
|
||||||
case OP_MMBIN: case OP_MMBINI: case OP_MMBINK: {
|
case OP_MMBIN: case OP_MMBINI: case OP_MMBINK: {
|
||||||
setobjs2s(L, base + GETARG_A(*(ci->u.l.savedpc - 2)), --L->top);
|
setobjs2s(L, base + GETARG_A(*(ci->u.l.savedpc - 2)), --L->top.p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_UNM: case OP_BNOT: case OP_LEN:
|
case OP_UNM: case OP_BNOT: case OP_LEN:
|
||||||
case OP_GETTABUP: case OP_GETTABLE: case OP_GETI:
|
case OP_GETTABUP: case OP_GETTABLE: case OP_GETI:
|
||||||
case OP_GETFIELD: case OP_SELF: {
|
case OP_GETFIELD: case OP_SELF: {
|
||||||
setobjs2s(L, base + GETARG_A(inst), --L->top);
|
setobjs2s(L, base + GETARG_A(inst), --L->top.p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_LT: case OP_LE:
|
case OP_LT: case OP_LE:
|
||||||
case OP_LTI: case OP_LEI:
|
case OP_LTI: case OP_LEI:
|
||||||
case OP_GTI: case OP_GEI:
|
case OP_GTI: case OP_GEI:
|
||||||
case OP_EQ: { /* note that 'OP_EQI'/'OP_EQK' cannot yield */
|
case OP_EQ: { /* note that 'OP_EQI'/'OP_EQK' cannot yield */
|
||||||
int res = !l_isfalse(s2v(L->top - 1));
|
int res = !l_isfalse(s2v(L->top.p - 1));
|
||||||
L->top--;
|
L->top.p--;
|
||||||
#if defined(LUA_COMPAT_LT_LE)
|
#if defined(LUA_COMPAT_LT_LE)
|
||||||
if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */
|
if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */
|
||||||
ci->callstatus ^= CIST_LEQ; /* clear mark */
|
ci->callstatus ^= CIST_LEQ; /* clear mark */
|
||||||
@ -840,11 +840,11 @@ void luaV_finishOp (lua_State *L) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_CONCAT: {
|
case OP_CONCAT: {
|
||||||
StkId top = L->top - 1; /* top when 'luaT_tryconcatTM' was called */
|
StkId top = L->top.p - 1; /* top when 'luaT_tryconcatTM' was called */
|
||||||
int a = GETARG_A(inst); /* first element to concatenate */
|
int a = GETARG_A(inst); /* first element to concatenate */
|
||||||
int total = cast_int(top - 1 - (base + a)); /* yet to concatenate */
|
int total = cast_int(top - 1 - (base + a)); /* yet to concatenate */
|
||||||
setobjs2s(L, top - 2, top); /* put TM result in proper position */
|
setobjs2s(L, top - 2, top); /* put TM result in proper position */
|
||||||
L->top = top - 1; /* top is one after last element (at top-2) */
|
L->top.p = top - 1; /* top is one after last element (at top-2) */
|
||||||
luaV_concat(L, total); /* concat them (may yield again) */
|
luaV_concat(L, total); /* concat them (may yield again) */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -856,7 +856,7 @@ void luaV_finishOp (lua_State *L) {
|
|||||||
StkId ra = base + GETARG_A(inst);
|
StkId ra = base + GETARG_A(inst);
|
||||||
/* adjust top to signal correct number of returns, in case the
|
/* adjust top to signal correct number of returns, in case the
|
||||||
return is "up to top" ('isIT') */
|
return is "up to top" ('isIT') */
|
||||||
L->top = ra + ci->u2.nres;
|
L->top.p = ra + ci->u2.nres;
|
||||||
/* repeat instruction to close other vars. and complete the return */
|
/* repeat instruction to close other vars. and complete the return */
|
||||||
ci->u.l.savedpc--;
|
ci->u.l.savedpc--;
|
||||||
break;
|
break;
|
||||||
@ -1069,7 +1069,7 @@ void luaV_finishOp (lua_State *L) {
|
|||||||
|
|
||||||
#define updatetrap(ci) (trap = ci->u.l.trap)
|
#define updatetrap(ci) (trap = ci->u.l.trap)
|
||||||
|
|
||||||
#define updatebase(ci) (base = ci->func + 1)
|
#define updatebase(ci) (base = ci->func.p + 1)
|
||||||
|
|
||||||
|
|
||||||
#define updatestack(ci) \
|
#define updatestack(ci) \
|
||||||
@ -1104,7 +1104,7 @@ void luaV_finishOp (lua_State *L) {
|
|||||||
** Whenever code can raise errors, the global 'pc' and the global
|
** Whenever code can raise errors, the global 'pc' and the global
|
||||||
** 'top' must be correct to report occasional errors.
|
** 'top' must be correct to report occasional errors.
|
||||||
*/
|
*/
|
||||||
#define savestate(L,ci) (savepc(L), L->top = ci->top)
|
#define savestate(L,ci) (savepc(L), L->top.p = ci->top.p)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1124,7 +1124,7 @@ void luaV_finishOp (lua_State *L) {
|
|||||||
|
|
||||||
/* 'c' is the limit of live values in the stack */
|
/* 'c' is the limit of live values in the stack */
|
||||||
#define checkGC(L,c) \
|
#define checkGC(L,c) \
|
||||||
{ luaC_condGC(L, (savepc(L), L->top = (c)), \
|
{ luaC_condGC(L, (savepc(L), L->top.p = (c)), \
|
||||||
updatetrap(ci)); \
|
updatetrap(ci)); \
|
||||||
luai_threadyield(L); }
|
luai_threadyield(L); }
|
||||||
|
|
||||||
@ -1155,7 +1155,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||||||
startfunc:
|
startfunc:
|
||||||
trap = L->hookmask;
|
trap = L->hookmask;
|
||||||
returning: /* trap already set */
|
returning: /* trap already set */
|
||||||
cl = clLvalue(s2v(ci->func));
|
cl = clLvalue(s2v(ci->func.p));
|
||||||
k = cl->p->k;
|
k = cl->p->k;
|
||||||
pc = ci->u.l.savedpc;
|
pc = ci->u.l.savedpc;
|
||||||
if (l_unlikely(trap)) {
|
if (l_unlikely(trap)) {
|
||||||
@ -1167,7 +1167,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||||||
}
|
}
|
||||||
ci->u.l.trap = 1; /* assume trap is on, for now */
|
ci->u.l.trap = 1; /* assume trap is on, for now */
|
||||||
}
|
}
|
||||||
base = ci->func + 1;
|
base = ci->func.p + 1;
|
||||||
/* main loop of interpreter */
|
/* main loop of interpreter */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
Instruction i; /* instruction being executed */
|
Instruction i; /* instruction being executed */
|
||||||
@ -1176,10 +1176,10 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||||||
/* low-level line tracing for debugging Lua */
|
/* low-level line tracing for debugging Lua */
|
||||||
printf("line: %d\n", luaG_getfuncline(cl->p, pcRel(pc, cl->p)));
|
printf("line: %d\n", luaG_getfuncline(cl->p, pcRel(pc, cl->p)));
|
||||||
#endif
|
#endif
|
||||||
lua_assert(base == ci->func + 1);
|
lua_assert(base == ci->func.p + 1);
|
||||||
lua_assert(base <= L->top && L->top <= L->stack_last);
|
lua_assert(base <= L->top.p && L->top.p <= L->stack_last.p);
|
||||||
/* invalidate top for instructions not expecting it */
|
/* invalidate top for instructions not expecting it */
|
||||||
lua_assert(isIT(i) || (cast_void(L->top = base), 1));
|
lua_assert(isIT(i) || (cast_void(L->top.p = base), 1));
|
||||||
vmdispatch (GET_OPCODE(i)) {
|
vmdispatch (GET_OPCODE(i)) {
|
||||||
vmcase(OP_MOVE) {
|
vmcase(OP_MOVE) {
|
||||||
StkId ra = RA(i);
|
StkId ra = RA(i);
|
||||||
@ -1238,20 +1238,20 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||||||
vmcase(OP_GETUPVAL) {
|
vmcase(OP_GETUPVAL) {
|
||||||
StkId ra = RA(i);
|
StkId ra = RA(i);
|
||||||
int b = GETARG_B(i);
|
int b = GETARG_B(i);
|
||||||
setobj2s(L, ra, cl->upvals[b]->v);
|
setobj2s(L, ra, cl->upvals[b]->v.p);
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_SETUPVAL) {
|
vmcase(OP_SETUPVAL) {
|
||||||
StkId ra = RA(i);
|
StkId ra = RA(i);
|
||||||
UpVal *uv = cl->upvals[GETARG_B(i)];
|
UpVal *uv = cl->upvals[GETARG_B(i)];
|
||||||
setobj(L, uv->v, s2v(ra));
|
setobj(L, uv->v.p, s2v(ra));
|
||||||
luaC_barrier(L, uv, s2v(ra));
|
luaC_barrier(L, uv, s2v(ra));
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_GETTABUP) {
|
vmcase(OP_GETTABUP) {
|
||||||
StkId ra = RA(i);
|
StkId ra = RA(i);
|
||||||
const TValue *slot;
|
const TValue *slot;
|
||||||
TValue *upval = cl->upvals[GETARG_B(i)]->v;
|
TValue *upval = cl->upvals[GETARG_B(i)]->v.p;
|
||||||
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, upval, key, slot, luaH_getshortstr)) {
|
if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) {
|
||||||
@ -1306,7 +1306,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||||||
}
|
}
|
||||||
vmcase(OP_SETTABUP) {
|
vmcase(OP_SETTABUP) {
|
||||||
const TValue *slot;
|
const TValue *slot;
|
||||||
TValue *upval = cl->upvals[GETARG_A(i)]->v;
|
TValue *upval = cl->upvals[GETARG_A(i)]->v.p;
|
||||||
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 */
|
||||||
@ -1371,7 +1371,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||||||
if (TESTARG_k(i)) /* non-zero extra argument? */
|
if (TESTARG_k(i)) /* non-zero extra argument? */
|
||||||
c += GETARG_Ax(*pc) * (MAXARG_C + 1); /* add it to size */
|
c += GETARG_Ax(*pc) * (MAXARG_C + 1); /* add it to size */
|
||||||
pc++; /* skip extra argument */
|
pc++; /* skip extra argument */
|
||||||
L->top = ra + 1; /* correct top in case of emergency GC */
|
L->top.p = ra + 1; /* correct top in case of emergency GC */
|
||||||
t = luaH_new(L); /* memory allocation */
|
t = luaH_new(L); /* memory allocation */
|
||||||
sethvalue2s(L, ra, t);
|
sethvalue2s(L, ra, t);
|
||||||
if (b != 0 || c != 0)
|
if (b != 0 || c != 0)
|
||||||
@ -1578,9 +1578,9 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||||||
vmcase(OP_CONCAT) {
|
vmcase(OP_CONCAT) {
|
||||||
StkId ra = RA(i);
|
StkId ra = RA(i);
|
||||||
int n = GETARG_B(i); /* number of elements to concatenate */
|
int n = GETARG_B(i); /* number of elements to concatenate */
|
||||||
L->top = ra + n; /* mark the end of concat operands */
|
L->top.p = ra + n; /* mark the end of concat operands */
|
||||||
ProtectNT(luaV_concat(L, n));
|
ProtectNT(luaV_concat(L, n));
|
||||||
checkGC(L, L->top); /* 'luaV_concat' ensures correct top */
|
checkGC(L, L->top.p); /* 'luaV_concat' ensures correct top */
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_CLOSE) {
|
vmcase(OP_CLOSE) {
|
||||||
@ -1674,7 +1674,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||||||
int b = GETARG_B(i);
|
int b = GETARG_B(i);
|
||||||
int nresults = GETARG_C(i) - 1;
|
int nresults = GETARG_C(i) - 1;
|
||||||
if (b != 0) /* fixed number of arguments? */
|
if (b != 0) /* fixed number of arguments? */
|
||||||
L->top = ra + b; /* top signals number of arguments */
|
L->top.p = ra + b; /* top signals number of arguments */
|
||||||
/* else previous instruction set top */
|
/* else previous instruction set top */
|
||||||
savepc(L); /* in case of errors */
|
savepc(L); /* in case of errors */
|
||||||
if ((newci = luaD_precall(L, ra, nresults)) == NULL)
|
if ((newci = luaD_precall(L, ra, nresults)) == NULL)
|
||||||
@ -1693,19 +1693,19 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||||||
/* delta is virtual 'func' - real 'func' (vararg functions) */
|
/* delta is virtual 'func' - real 'func' (vararg functions) */
|
||||||
int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0;
|
int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0;
|
||||||
if (b != 0)
|
if (b != 0)
|
||||||
L->top = ra + b;
|
L->top.p = ra + b;
|
||||||
else /* previous instruction set top */
|
else /* previous instruction set top */
|
||||||
b = cast_int(L->top - ra);
|
b = cast_int(L->top.p - ra);
|
||||||
savepc(ci); /* several calls here can raise errors */
|
savepc(ci); /* several calls here can raise errors */
|
||||||
if (TESTARG_k(i)) {
|
if (TESTARG_k(i)) {
|
||||||
luaF_closeupval(L, base); /* close upvalues from current call */
|
luaF_closeupval(L, base); /* close upvalues from current call */
|
||||||
lua_assert(L->tbclist < base); /* no pending tbc variables */
|
lua_assert(L->tbclist.p < base); /* no pending tbc variables */
|
||||||
lua_assert(base == ci->func + 1);
|
lua_assert(base == ci->func.p + 1);
|
||||||
}
|
}
|
||||||
if ((n = luaD_pretailcall(L, ci, ra, b, delta)) < 0) /* Lua function? */
|
if ((n = luaD_pretailcall(L, ci, ra, b, delta)) < 0) /* Lua function? */
|
||||||
goto startfunc; /* execute the callee */
|
goto startfunc; /* execute the callee */
|
||||||
else { /* C function? */
|
else { /* C function? */
|
||||||
ci->func -= delta; /* restore 'func' (if vararg) */
|
ci->func.p -= delta; /* restore 'func' (if vararg) */
|
||||||
luaD_poscall(L, ci, n); /* finish caller */
|
luaD_poscall(L, ci, n); /* finish caller */
|
||||||
updatetrap(ci); /* 'luaD_poscall' can change hooks */
|
updatetrap(ci); /* 'luaD_poscall' can change hooks */
|
||||||
goto ret; /* caller returns after the tail call */
|
goto ret; /* caller returns after the tail call */
|
||||||
@ -1716,19 +1716,19 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||||||
int n = GETARG_B(i) - 1; /* number of results */
|
int n = GETARG_B(i) - 1; /* number of results */
|
||||||
int nparams1 = GETARG_C(i);
|
int nparams1 = GETARG_C(i);
|
||||||
if (n < 0) /* not fixed? */
|
if (n < 0) /* not fixed? */
|
||||||
n = cast_int(L->top - ra); /* get what is available */
|
n = cast_int(L->top.p - ra); /* get what is available */
|
||||||
savepc(ci);
|
savepc(ci);
|
||||||
if (TESTARG_k(i)) { /* may there be open upvalues? */
|
if (TESTARG_k(i)) { /* may there be open upvalues? */
|
||||||
ci->u2.nres = n; /* save number of returns */
|
ci->u2.nres = n; /* save number of returns */
|
||||||
if (L->top < ci->top)
|
if (L->top.p < ci->top.p)
|
||||||
L->top = ci->top;
|
L->top.p = ci->top.p;
|
||||||
luaF_close(L, base, CLOSEKTOP, 1);
|
luaF_close(L, base, CLOSEKTOP, 1);
|
||||||
updatetrap(ci);
|
updatetrap(ci);
|
||||||
updatestack(ci);
|
updatestack(ci);
|
||||||
}
|
}
|
||||||
if (nparams1) /* vararg function? */
|
if (nparams1) /* vararg function? */
|
||||||
ci->func -= ci->u.l.nextraargs + nparams1;
|
ci->func.p -= ci->u.l.nextraargs + nparams1;
|
||||||
L->top = ra + n; /* set call for 'luaD_poscall' */
|
L->top.p = ra + n; /* set call for 'luaD_poscall' */
|
||||||
luaD_poscall(L, ci, n);
|
luaD_poscall(L, ci, n);
|
||||||
updatetrap(ci); /* 'luaD_poscall' can change hooks */
|
updatetrap(ci); /* 'luaD_poscall' can change hooks */
|
||||||
goto ret;
|
goto ret;
|
||||||
@ -1736,7 +1736,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||||||
vmcase(OP_RETURN0) {
|
vmcase(OP_RETURN0) {
|
||||||
if (l_unlikely(L->hookmask)) {
|
if (l_unlikely(L->hookmask)) {
|
||||||
StkId ra = RA(i);
|
StkId ra = RA(i);
|
||||||
L->top = ra;
|
L->top.p = ra;
|
||||||
savepc(ci);
|
savepc(ci);
|
||||||
luaD_poscall(L, ci, 0); /* no hurry... */
|
luaD_poscall(L, ci, 0); /* no hurry... */
|
||||||
trap = 1;
|
trap = 1;
|
||||||
@ -1744,16 +1744,16 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||||||
else { /* do the 'poscall' here */
|
else { /* do the 'poscall' here */
|
||||||
int nres;
|
int nres;
|
||||||
L->ci = ci->previous; /* back to caller */
|
L->ci = ci->previous; /* back to caller */
|
||||||
L->top = base - 1;
|
L->top.p = base - 1;
|
||||||
for (nres = ci->nresults; l_unlikely(nres > 0); nres--)
|
for (nres = ci->nresults; l_unlikely(nres > 0); nres--)
|
||||||
setnilvalue(s2v(L->top++)); /* all results are nil */
|
setnilvalue(s2v(L->top.p++)); /* all results are nil */
|
||||||
}
|
}
|
||||||
goto ret;
|
goto ret;
|
||||||
}
|
}
|
||||||
vmcase(OP_RETURN1) {
|
vmcase(OP_RETURN1) {
|
||||||
if (l_unlikely(L->hookmask)) {
|
if (l_unlikely(L->hookmask)) {
|
||||||
StkId ra = RA(i);
|
StkId ra = RA(i);
|
||||||
L->top = ra + 1;
|
L->top.p = ra + 1;
|
||||||
savepc(ci);
|
savepc(ci);
|
||||||
luaD_poscall(L, ci, 1); /* no hurry... */
|
luaD_poscall(L, ci, 1); /* no hurry... */
|
||||||
trap = 1;
|
trap = 1;
|
||||||
@ -1762,13 +1762,13 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||||||
int nres = ci->nresults;
|
int nres = ci->nresults;
|
||||||
L->ci = ci->previous; /* back to caller */
|
L->ci = ci->previous; /* back to caller */
|
||||||
if (nres == 0)
|
if (nres == 0)
|
||||||
L->top = base - 1; /* asked for no results */
|
L->top.p = base - 1; /* asked for no results */
|
||||||
else {
|
else {
|
||||||
StkId ra = RA(i);
|
StkId ra = RA(i);
|
||||||
setobjs2s(L, base - 1, ra); /* at least this result */
|
setobjs2s(L, base - 1, ra); /* at least this result */
|
||||||
L->top = base;
|
L->top.p = base;
|
||||||
for (; l_unlikely(nres > 1); nres--)
|
for (; l_unlikely(nres > 1); nres--)
|
||||||
setnilvalue(s2v(L->top++)); /* complete missing results */
|
setnilvalue(s2v(L->top.p++)); /* complete missing results */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret: /* return from a Lua function */
|
ret: /* return from a Lua function */
|
||||||
@ -1824,7 +1824,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||||||
*/
|
*/
|
||||||
/* push function, state, and control variable */
|
/* push function, state, and control variable */
|
||||||
memcpy(ra + 4, ra, 3 * sizeof(*ra));
|
memcpy(ra + 4, ra, 3 * sizeof(*ra));
|
||||||
L->top = ra + 4 + 3;
|
L->top.p = ra + 4 + 3;
|
||||||
ProtectNT(luaD_call(L, ra + 4, GETARG_C(i))); /* do the call */
|
ProtectNT(luaD_call(L, ra + 4, GETARG_C(i))); /* do the call */
|
||||||
updatestack(ci); /* stack may have changed */
|
updatestack(ci); /* stack may have changed */
|
||||||
i = *(pc++); /* go to next instruction */
|
i = *(pc++); /* go to next instruction */
|
||||||
@ -1846,9 +1846,9 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||||||
unsigned int last = GETARG_C(i);
|
unsigned int last = GETARG_C(i);
|
||||||
Table *h = hvalue(s2v(ra));
|
Table *h = hvalue(s2v(ra));
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
n = cast_int(L->top - ra) - 1; /* get up to the top */
|
n = cast_int(L->top.p - ra) - 1; /* get up to the top */
|
||||||
else
|
else
|
||||||
L->top = ci->top; /* correct top in case of emergency GC */
|
L->top.p = ci->top.p; /* correct top in case of emergency GC */
|
||||||
last += n;
|
last += n;
|
||||||
if (TESTARG_k(i)) {
|
if (TESTARG_k(i)) {
|
||||||
last += GETARG_Ax(*pc) * (MAXARG_C + 1);
|
last += GETARG_Ax(*pc) * (MAXARG_C + 1);
|
||||||
|
Loading…
Reference in New Issue
Block a user