mirror of
https://github.com/lua/lua
synced 2024-11-22 12:51:30 +03:00
when running Lua code, there is no need to keep 'L->top' "correct";
set it only when needed.
This commit is contained in:
parent
4dc0be950a
commit
1d5b885437
19
ldebug.c
19
ldebug.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ldebug.c,v 2.148 2017/12/13 18:32:09 roberto Exp roberto $
|
||||
** $Id: ldebug.c,v 2.149 2017/12/15 13:07:10 roberto Exp roberto $
|
||||
** Debug Interface
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -189,14 +189,10 @@ static const char *upvalname (Proto *p, int uv) {
|
||||
|
||||
static const char *findlocal (lua_State *L, CallInfo *ci, int n,
|
||||
StkId *pos) {
|
||||
const char *name = NULL;
|
||||
StkId base;
|
||||
if (isLua(ci)) {
|
||||
base = ci->func + 1;
|
||||
name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
|
||||
}
|
||||
else
|
||||
base = ci->func + 1;
|
||||
StkId base = ci->func + 1;
|
||||
const char *name = (isLua(ci))
|
||||
? luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci))
|
||||
: NULL;
|
||||
if (name == NULL) { /* no 'standard' name? */
|
||||
StkId limit = (ci == L->ci) ? L->top : ci->next->func;
|
||||
if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */
|
||||
@ -741,6 +737,8 @@ l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
|
||||
const char *msg;
|
||||
va_list argp;
|
||||
luaC_checkGC(L); /* error message uses memory */
|
||||
if (isLuacode(ci))
|
||||
L->top = ci->top; /* prepare top */
|
||||
va_start(argp, fmt);
|
||||
msg = luaO_pushvfstring(L, fmt, argp); /* format message */
|
||||
va_end(argp);
|
||||
@ -764,6 +762,7 @@ static int changedline (Proto *p, int oldpc, int newpc) {
|
||||
|
||||
|
||||
void luaG_traceexec (lua_State *L) {
|
||||
ptrdiff_t oldtop = savestack(L, L->top);
|
||||
CallInfo *ci = L->ci;
|
||||
lu_byte mask = L->hookmask;
|
||||
int counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT));
|
||||
@ -775,6 +774,7 @@ void luaG_traceexec (lua_State *L) {
|
||||
ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */
|
||||
return; /* do not call hook again (VM yielded, so it did not move) */
|
||||
}
|
||||
L->top = ci->top; /* prepare top */
|
||||
if (counthook)
|
||||
luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */
|
||||
if (mask & LUA_MASKLINE) {
|
||||
@ -789,6 +789,7 @@ void luaG_traceexec (lua_State *L) {
|
||||
}
|
||||
L->oldpc = npc;
|
||||
}
|
||||
L->top = restorestack(L, oldtop);
|
||||
if (L->status == LUA_YIELD) { /* did hook yield? */
|
||||
if (counthook)
|
||||
L->hookcount = 1; /* undo decrement to zero */
|
||||
|
9
ldo.c
9
ldo.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ldo.c,v 2.181 2017/12/15 13:07:10 roberto Exp roberto $
|
||||
** $Id: ldo.c,v 2.182 2017/12/19 16:40:17 roberto Exp roberto $
|
||||
** Stack and Call structure of Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -299,6 +299,7 @@ static void callhook (lua_State *L, CallInfo *ci, int istail) {
|
||||
ci->u.l.trap = 1;
|
||||
if (!(L->hookmask & LUA_MASKCALL))
|
||||
return; /* some other hook */
|
||||
L->top = ci->top; /* prepare top */
|
||||
ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */
|
||||
if (istail) {
|
||||
ci->callstatus |= CIST_TAIL;
|
||||
@ -312,6 +313,8 @@ static void callhook (lua_State *L, CallInfo *ci, int istail) {
|
||||
|
||||
|
||||
static void rethook (lua_State *L, CallInfo *ci) {
|
||||
if (isLuacode(ci))
|
||||
L->top = ci->top; /* prepare top */
|
||||
if (L->hookmask & LUA_MASKRET) /* is return hook on? */
|
||||
luaD_hook(L, LUA_HOOKRET, -1); /* call it */
|
||||
if (isLua(ci->previous))
|
||||
@ -421,7 +424,7 @@ void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int n) {
|
||||
L->top -= (func - ci->func); /* move down top */
|
||||
luaT_adjustvarargs(L, p, n - 1);
|
||||
}
|
||||
L->top = ci->top = ci->func + 1 + fsize; /* top for new function */
|
||||
ci->top = ci->func + 1 + fsize; /* top for new function */
|
||||
lua_assert(ci->top <= L->stack_last);
|
||||
ci->u.l.savedpc = p->code; /* starting point */
|
||||
ci->callstatus |= CIST_TAIL;
|
||||
@ -476,7 +479,7 @@ void luaD_call (lua_State *L, StkId func, int nresults) {
|
||||
ci = next_ci(L); /* now 'enter' new function */
|
||||
ci->nresults = nresults;
|
||||
ci->func = func;
|
||||
L->top = ci->top = func + 1 + fsize;
|
||||
ci->top = func + 1 + fsize;
|
||||
lua_assert(ci->top <= L->stack_last);
|
||||
ci->u.l.savedpc = p->code; /* starting point */
|
||||
ci->callstatus = 0;
|
||||
|
14
lgc.c
14
lgc.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lgc.c,v 2.241 2017/12/01 17:38:49 roberto Exp roberto $
|
||||
** $Id: lgc.c,v 2.242 2017/12/08 17:28:25 roberto Exp roberto $
|
||||
** Garbage Collector
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -569,13 +569,23 @@ static int traverseLclosure (global_State *g, LClosure *cl) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Traverse a thread, marking the elements in the stack up to its top
|
||||
** and cleaning the rest of the stack in the last traversal.
|
||||
** That ensures that the entire stack have valid (non-dead) objects.
|
||||
** In an emergency collection running Lua code, 'L->top' may not be
|
||||
** update. In that case, traverse at least up to 'ci->top'.
|
||||
*/
|
||||
static int traversethread (global_State *g, lua_State *th) {
|
||||
StkId o = th->stack;
|
||||
StkId top = th->top;
|
||||
if (o == NULL)
|
||||
return 1; /* stack not completely built yet */
|
||||
lua_assert(g->gcstate == GCSatomic ||
|
||||
th->openupval == NULL || isintwups(th));
|
||||
for (; o < th->top; o++) /* mark live elements in the stack */
|
||||
if (g->gcemergency && isLuacode(th->ci) && top < th->ci->top)
|
||||
top = th->ci->top;
|
||||
for (; o < top; o++) /* mark live elements in the stack */
|
||||
markvalue(g, s2v(o));
|
||||
if (g->gcstate == GCSatomic) { /* final traversal? */
|
||||
StkId lim = th->stack + th->stacksize; /* real end of stack */
|
||||
|
26
ltm.c
26
ltm.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltm.c,v 2.53 2017/12/15 13:07:10 roberto Exp roberto $
|
||||
** $Id: ltm.c,v 2.54 2017/12/19 16:40:17 roberto Exp roberto $
|
||||
** Tag methods
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -101,12 +101,12 @@ const char *luaT_objtypename (lua_State *L, const TValue *o) {
|
||||
|
||||
void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
|
||||
const TValue *p2, const TValue *p3) {
|
||||
StkId func = L->top;
|
||||
StkId func = (isLuacode(L->ci)) ? L->ci->top : L->top;
|
||||
setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */
|
||||
setobj2s(L, func + 1, p1); /* 1st argument */
|
||||
setobj2s(L, func + 2, p2); /* 2nd argument */
|
||||
setobj2s(L, func + 3, p3); /* 3rd argument */
|
||||
L->top += 4;
|
||||
L->top = func + 4;
|
||||
/* metamethod may yield only when called from Lua code */
|
||||
if (isLuacode(L->ci))
|
||||
luaD_call(L, func, 0);
|
||||
@ -115,8 +115,8 @@ void luaT_callTM (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) {
|
||||
static void reallycallTMres (lua_State *L, const TValue *f, const TValue *p1,
|
||||
const TValue *p2, StkId res) {
|
||||
ptrdiff_t result = savestack(L, res);
|
||||
StkId func = L->top;
|
||||
setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */
|
||||
@ -129,7 +129,15 @@ void luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1,
|
||||
else
|
||||
luaD_callnoyield(L, func, 1);
|
||||
res = restorestack(L, result);
|
||||
setobjs2s(L, res, --L->top); /* more result to its place */
|
||||
setobjs2s(L, res, --L->top); /* move result to its place */
|
||||
}
|
||||
|
||||
|
||||
void luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1,
|
||||
const TValue *p2, StkId res) {
|
||||
if (isLuacode(L->ci))
|
||||
L->top = L->ci->top; /* prepare top */
|
||||
reallycallTMres(L, f, p1, p2, res);
|
||||
}
|
||||
|
||||
|
||||
@ -139,13 +147,15 @@ static int callbinTM (lua_State *L, const TValue *p1, const TValue *p2,
|
||||
if (ttisnil(tm))
|
||||
tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
|
||||
if (ttisnil(tm)) return 0;
|
||||
luaT_callTMres(L, tm, p1, p2, res);
|
||||
reallycallTMres(L, tm, p1, p2, res);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
|
||||
StkId res, TMS event) {
|
||||
if (event != TM_CONCAT && isLuacode(L->ci))
|
||||
L->top = L->ci->top; /* prepare top */
|
||||
if (!callbinTM(L, p1, p2, res, event)) {
|
||||
switch (event) {
|
||||
case TM_CONCAT:
|
||||
@ -185,6 +195,8 @@ void luaT_trybiniTM (lua_State *L, const TValue *p1, int i2,
|
||||
|
||||
int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2,
|
||||
TMS event) {
|
||||
if (isLuacode(L->ci))
|
||||
L->top = L->ci->top; /* prepare top */
|
||||
if (callbinTM(L, p1, p2, L->top, event)) /* try original event */
|
||||
return !l_isfalse(s2v(L->top));
|
||||
else if (event == TM_LE) {
|
||||
|
26
lvm.c
26
lvm.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lvm.c,v 2.326 2017/12/18 17:53:50 roberto Exp roberto $
|
||||
** $Id: lvm.c,v 2.327 2017/12/19 16:18:04 roberto Exp roberto $
|
||||
** Lua virtual machine
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -464,6 +464,8 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
|
||||
}
|
||||
if (tm == NULL) /* no TM? */
|
||||
return 0; /* objects are different */
|
||||
if (isLuacode(L->ci))
|
||||
L->top = L->ci->top; /* prepare top */
|
||||
luaT_callTMres(L, tm, t1, t2, L->top); /* call TM */
|
||||
return !l_isfalse(s2v(L->top));
|
||||
}
|
||||
@ -726,20 +728,10 @@ void luaV_finishOp (lua_State *L) {
|
||||
}
|
||||
/* move final result to final position */
|
||||
setobjs2s(L, ci->func + 1 + GETARG_A(inst), L->top - 1);
|
||||
L->top = ci->top; /* restore top */
|
||||
break;
|
||||
}
|
||||
case OP_TFORCALL: {
|
||||
lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP);
|
||||
L->top = ci->top; /* correct top */
|
||||
break;
|
||||
}
|
||||
case OP_CALL: {
|
||||
if (GETARG_C(inst) - 1 >= 0) /* nresults >= 0? */
|
||||
L->top = ci->top; /* adjust results */
|
||||
break;
|
||||
}
|
||||
case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE:
|
||||
case OP_TFORCALL: case OP_CALL: case OP_TAILCALL:
|
||||
case OP_SETTABUP: case OP_SETTABLE:
|
||||
case OP_SETI: case OP_SETFIELD:
|
||||
break;
|
||||
default: lua_assert(0);
|
||||
@ -808,7 +800,7 @@ void luaV_finishOp (lua_State *L) {
|
||||
|
||||
#define checkGC(L,c) \
|
||||
{ luaC_condGC(L, L->top = (c), /* limit of live values */ \
|
||||
(L->top = ci->top, updatetrap(ci))); /* restore top */ \
|
||||
updatetrap(ci)); \
|
||||
luai_threadyield(L); }
|
||||
|
||||
|
||||
@ -1387,7 +1379,6 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||
rb = base + b;
|
||||
setobjs2s(L, ra, rb);
|
||||
checkGC(L, (ra >= rb ? ra + 1 : rb));
|
||||
L->top = ci->top; /* restore top */
|
||||
vmbreak;
|
||||
}
|
||||
vmcase(OP_CLOSE) {
|
||||
@ -1491,9 +1482,6 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||
L->top = ra + b; /* top signals number of arguments */
|
||||
/* else previous instruction set top */
|
||||
Protect(luaD_call(L, ra, nresults));
|
||||
if (nresults >= 0) /* fixed number of results? */
|
||||
L->top = ci->top; /* correct top */
|
||||
/* else leave top for next instruction */
|
||||
vmbreak;
|
||||
}
|
||||
vmcase(OP_TAILCALL) {
|
||||
@ -1651,7 +1639,6 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||
setobjs2s(L, cb, ra);
|
||||
L->top = cb + 3; /* func. + 2 args (state and index) */
|
||||
Protect(luaD_call(L, cb, GETARG_C(i)));
|
||||
L->top = ci->top;
|
||||
if (trap) /* keep 'base' correct for next instruction */
|
||||
updatebase(ci);
|
||||
i = *(pc++); /* go to next instruction */
|
||||
@ -1686,7 +1673,6 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||
last--;
|
||||
luaC_barrierback(L, h, val);
|
||||
}
|
||||
L->top = ci->top; /* correct top (in case of previous open call) */
|
||||
vmbreak;
|
||||
}
|
||||
vmcase(OP_CLOSURE) {
|
||||
|
Loading…
Reference in New Issue
Block a user