From 196c87c9cecfacf978f37de4ec69eba0a5971256 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy <roberto@inf.puc-rio.br> Date: Thu, 23 Nov 2017 14:41:16 -0200 Subject: no more 'stackless' implementation; 'luaV_execute' calls itself recursively to execute function calls. 'unroll' continues all executions suspended by an yield (through a long jump) --- ldo.c | 66 ++++++++++++++++++------------------------------------------------ 1 file changed, 18 insertions(+), 48 deletions(-) (limited to 'ldo.c') diff --git a/ldo.c b/ldo.c index 30954123..6b8162d2 100644 --- a/ldo.c +++ b/ldo.c @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 2.172 2017/11/13 15:36:52 roberto Exp roberto $ +** $Id: ldo.c,v 2.173 2017/11/21 14:17:35 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -135,7 +135,7 @@ l_noret luaD_throw (lua_State *L, int errcode) { int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { - unsigned short oldnCcalls = L->nCcalls; + unsigned short oldnCcalls = L->nCcalls - L->nci; struct lua_longjmp lj; lj.status = LUA_OK; lj.previous = L->errorJmp; /* chain new error handler */ @@ -144,7 +144,7 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { (*f)(L, ud); ); L->errorJmp = lj.previous; /* restore old error handler */ - L->nCcalls = oldnCcalls; + L->nCcalls = oldnCcalls + L->nci; return lj.status; } @@ -299,7 +299,7 @@ static void callhook (lua_State *L, CallInfo *ci, int istail) { /* ** Check whether __call metafield of 'func' is a function. If so, put -** it in stack below original 'func' so that 'luaD_precall' can call +** it in stack below original 'func' so that 'luaD_call' can call ** it. Raise an error if __call metafield is not a function. */ StkId luaD_tryfuncTM (lua_State *L, StkId func) { @@ -417,13 +417,12 @@ void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int n) { /* -** Prepares a function call: checks the stack, creates a new CallInfo -** entry, fills in the relevant information, calls hook if needed. -** If function is a C function, does the call, too. (Otherwise, leave -** the execution ('luaV_execute') to the caller, to allow stackless -** calls.) Returns true iff function has been executed (C function). +** Call a function (C or Lua). The function to be called is at *func. +** The arguments are on the stack, right after the function. +** When returns, all the results are on the stack, starting at the original +** function position. */ -int luaD_precall (lua_State *L, StkId func, int nresults) { +void luaD_call (lua_State *L, StkId func, int nresults) { lua_CFunction f; TValue *funcv = s2v(func); CallInfo *ci; @@ -449,7 +448,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { lua_lock(L); api_checknelems(L, n); luaD_poscall(L, ci, L->top - n, n); - return 1; + break; } case LUA_TLCL: { /* Lua function: prepare its call */ Proto *p = clLvalue(funcv)->p; @@ -469,46 +468,18 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { ci->callstatus = CIST_LUA; if (L->hookmask) callhook(L, ci, 0); - return 0; + luaV_execute(L); /* run the function */ + break; } default: { /* not a function */ func = luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */ - return luaD_precall(L, func, nresults); /* now it must be a function */ + luaD_call(L, func, nresults); /* now it must be a function */ + break; } } } -/* -** Check appropriate error for stack overflow ("regular" overflow or -** overflow while handling stack overflow). If 'nCalls' is larger than -** LUAI_MAXCCALLS (which means it is handling a "regular" overflow) but -** smaller than 9/8 of LUAI_MAXCCALLS, does not report an error (to -** allow overflow handling to work) -*/ -static void stackerror (lua_State *L) { - if (L->nCcalls == LUAI_MAXCCALLS) - luaG_runerror(L, "C stack overflow"); - else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) - luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ -} - - -/* -** Call a function (C or Lua). The function to be called is at *func. -** The arguments are on the stack, right after the function. -** When returns, all the results are on the stack, starting at the original -** function position. -*/ -void luaD_call (lua_State *L, StkId func, int nResults) { - if (++L->nCcalls >= LUAI_MAXCCALLS) - stackerror(L); - if (!luaD_precall(L, func, nResults)) /* is a Lua function? */ - luaV_execute(L); /* call it */ - L->nCcalls--; -} - - /* ** Similar to 'luaD_call', but does not allow yields during the call */ @@ -541,7 +512,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_precall' */ + luaD_poscall(L, ci, L->top - n, n); /* finish 'luaD_call' */ } @@ -629,8 +600,7 @@ static void resume (lua_State *L, void *ud) { StkId firstArg = L->top - n; /* first argument */ CallInfo *ci = L->ci; if (L->status == LUA_OK) { /* starting a coroutine? */ - if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */ - luaV_execute(L); /* call it */ + luaD_call(L, firstArg - 1, LUA_MULTRET); } else { /* resuming from previous yield */ lua_assert(L->status == LUA_YIELD); @@ -645,7 +615,7 @@ static void resume (lua_State *L, void *ud) { api_checknelems(L, n); firstArg = L->top - n; /* yield results come from continuation */ } - luaD_poscall(L, ci, firstArg, n); /* finish 'luaD_precall' */ + luaD_poscall(L, ci, firstArg, n); /* finish 'luaD_call' */ } unroll(L, NULL); /* run continuation */ } @@ -688,7 +658,7 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs, : L->top - (L->ci->func + 1); L->nny = oldnny; /* restore 'nny' */ L->nCcalls--; - lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0)); + // lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0)); lua_unlock(L); return status; } -- cgit v1.2.3-55-g6feb