|
@@ -1,5 +1,5 @@
|
|
|
/*
|
|
|
-** $Id: ldo.c,v 2.199 2018/03/07 16:26:01 roberto Exp roberto $
|
|
|
+** $Id: ldo.c,v 2.200 2018/03/16 15:33:34 roberto Exp roberto $
|
|
|
** Stack and Call structure of Lua
|
|
|
** See Copyright Notice in lua.h
|
|
|
*/
|
|
@@ -319,14 +319,15 @@ void luaD_hookcall (lua_State *L, CallInfo *ci) {
|
|
|
}
|
|
|
|
|
|
|
|
|
-static void rethook (lua_State *L, CallInfo *ci, StkId firstres, int nres) {
|
|
|
+static StkId rethook (lua_State *L, CallInfo *ci, StkId firstres, int nres) {
|
|
|
+ ptrdiff_t oldtop = savestack(L, L->top); /* hook may change top */
|
|
|
int delta = 0;
|
|
|
if (isLuacode(ci)) {
|
|
|
Proto *p = clLvalue(s2v(ci->func))->p;
|
|
|
if (p->is_vararg)
|
|
|
delta = ci->u.l.nextraargs + p->numparams + 1;
|
|
|
if (L->top < ci->top)
|
|
|
- L->top = ci->top; /* correct top */
|
|
|
+ L->top = ci->top; /* correct top to run hook */
|
|
|
}
|
|
|
if (L->hookmask & LUA_MASKRET) { /* is return hook on? */
|
|
|
int ftransfer;
|
|
@@ -337,6 +338,7 @@ static void rethook (lua_State *L, CallInfo *ci, StkId firstres, int nres) {
|
|
|
}
|
|
|
if (isLua(ci->previous))
|
|
|
L->oldpc = ci->previous->u.l.savedpc; /* update 'oldpc' */
|
|
|
+ return restorestack(L, oldtop);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -363,40 +365,33 @@ void luaD_tryfuncTM (lua_State *L, StkId func) {
|
|
|
** expressions, multiple results for tail calls/single parameters)
|
|
|
** separated.
|
|
|
*/
|
|
|
-static void moveresults (lua_State *L, StkId firstResult, StkId res,
|
|
|
- int nres, int wanted) {
|
|
|
+static void moveresults (lua_State *L, StkId res, int nres, int wanted) {
|
|
|
switch (wanted) { /* handle typical cases separately */
|
|
|
- case 0: break; /* nothing to move */
|
|
|
- case 1: { /* one result needed */
|
|
|
+ case 0: /* no values needed */
|
|
|
+ L->top = res;
|
|
|
+ break;
|
|
|
+ case 1: /* one value needed */
|
|
|
if (nres == 0) /* no results? */
|
|
|
setnilvalue(s2v(res)); /* adjust with nil */
|
|
|
else
|
|
|
- setobjs2s(L, res, firstResult); /* move it to proper place */
|
|
|
+ setobjs2s(L, res, L->top - nres); /* move it to proper place */
|
|
|
+ L->top = res + 1;
|
|
|
break;
|
|
|
- }
|
|
|
- case LUA_MULTRET: {
|
|
|
+ case LUA_MULTRET:
|
|
|
+ wanted = nres; /* we want all results */
|
|
|
+ /* FALLTHROUGH */
|
|
|
+ default: { /* multiple results */
|
|
|
+ StkId firstresult = L->top - nres; /* index of first result */
|
|
|
int i;
|
|
|
- for (i = 0; i < nres; i++) /* move all results to correct place */
|
|
|
- setobjs2s(L, res + i, firstResult + i);
|
|
|
- wanted = nres; /* it wanted what it had */
|
|
|
- break;
|
|
|
- }
|
|
|
- default: {
|
|
|
- int i;
|
|
|
- if (wanted <= nres) { /* enough results? */
|
|
|
- for (i = 0; i < wanted; i++) /* move wanted results to correct place */
|
|
|
- setobjs2s(L, res + i, firstResult + i);
|
|
|
- }
|
|
|
- else { /* not enough results; use all of them plus nils */
|
|
|
- for (i = 0; i < nres; i++) /* move all results to correct place */
|
|
|
- setobjs2s(L, res + i, firstResult + i);
|
|
|
- for (; i < wanted; i++) /* complete wanted number of results */
|
|
|
- setnilvalue(s2v(res + i));
|
|
|
- }
|
|
|
+ /* move all results to correct place */
|
|
|
+ for (i = 0; i < nres && i < wanted; i++)
|
|
|
+ setobjs2s(L, res + i, firstresult + i);
|
|
|
+ for (; i < wanted; i++) /* complete wanted number of results */
|
|
|
+ setnilvalue(s2v(res + i));
|
|
|
+ L->top = res + wanted; /* top points after the last result */
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
- L->top = res + wanted; /* top points after the last result */
|
|
|
}
|
|
|
|
|
|
|
|
@@ -404,15 +399,12 @@ static void moveresults (lua_State *L, StkId firstResult, StkId res,
|
|
|
** Finishes a function call: calls hook if necessary, removes CallInfo,
|
|
|
** moves current number of results to proper place.
|
|
|
*/
|
|
|
-void luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) {
|
|
|
- if (L->hookmask) {
|
|
|
- ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */
|
|
|
- rethook(L, ci, firstResult, nres);
|
|
|
- firstResult = restorestack(L, fr);
|
|
|
- }
|
|
|
+void luaD_poscall (lua_State *L, CallInfo *ci, int nres) {
|
|
|
+ if (L->hookmask)
|
|
|
+ L->top = rethook(L, ci, L->top - nres, nres);
|
|
|
L->ci = ci->previous; /* back to caller */
|
|
|
/* move results to proper place */
|
|
|
- moveresults(L, firstResult, ci->func, nres, ci->nresults);
|
|
|
+ moveresults(L, ci->func, nres, ci->nresults);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -477,7 +469,7 @@ void luaD_call (lua_State *L, StkId func, int nresults) {
|
|
|
n = (*f)(L); /* do the actual call */
|
|
|
lua_lock(L);
|
|
|
api_checknelems(L, n);
|
|
|
- luaD_poscall(L, ci, L->top - n, n);
|
|
|
+ luaD_poscall(L, ci, n);
|
|
|
break;
|
|
|
}
|
|
|
case LUA_TLCL: { /* Lua function */
|
|
@@ -540,7 +532,7 @@ static void finishCcall (lua_State *L, int status) {
|
|
|
n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation function */
|
|
|
lua_lock(L);
|
|
|
api_checknelems(L, n);
|
|
|
- luaD_poscall(L, ci, L->top - n, n); /* finish 'luaD_call' */
|
|
|
+ luaD_poscall(L, ci, n); /* finish 'luaD_call' */
|
|
|
}
|
|
|
|
|
|
|
|
@@ -642,9 +634,8 @@ static void resume (lua_State *L, void *ud) {
|
|
|
n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */
|
|
|
lua_lock(L);
|
|
|
api_checknelems(L, n);
|
|
|
- firstArg = L->top - n; /* yield results come from continuation */
|
|
|
}
|
|
|
- luaD_poscall(L, ci, firstArg, n); /* finish 'luaD_call' */
|
|
|
+ luaD_poscall(L, ci, n); /* finish 'luaD_call' */
|
|
|
}
|
|
|
unroll(L, NULL); /* run continuation */
|
|
|
}
|