Added "cost" for the use of C stack by a coroutine invocation.

Resuming a coroutine uses more C stack than other operations (such as
function calls or recursive syntax). So, to avoid stack overflow
in recursive coroutine invocations, either LUAI_MAXCCALLS must be
too small or a coroutine invocation must "pay" a higher price.
New constant LUAL_COROCSTK ("COROutine C STaK") defines how much
is this price.
This commit is contained in:
Roberto Ierusalimschy 2018-09-11 14:24:14 -03:00
parent 9cbf17b0f1
commit b114c7d487
1 changed files with 8 additions and 2 deletions

10
ldo.c
View File

@ -610,6 +610,13 @@ static int resume_error (lua_State *L, const char *msg, int narg) {
} }
/*
** "Cost" in the C stack for a coroutine invocation.
*/
#if !defined(LUAL_COROCSTK)
#define LUAL_COROCSTK 3
#endif
/* /*
** Do the work for 'lua_resume' in protected mode. Most of the work ** Do the work for 'lua_resume' in protected mode. Most of the work
** depends on the status of the coroutine: initial state, suspended ** depends on the status of the coroutine: initial state, suspended
@ -642,7 +649,6 @@ static void resume (lua_State *L, void *ud) {
} }
} }
LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs, LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs,
int *nresults) { int *nresults) {
int status; int status;
@ -657,7 +663,7 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs,
if (from == NULL) if (from == NULL)
L->nCcalls = 1; L->nCcalls = 1;
else /* correct 'nCcalls' for this thread */ else /* correct 'nCcalls' for this thread */
L->nCcalls = from->nCcalls - from->nci + L->nci + 1; L->nCcalls = from->nCcalls - from->nci + L->nci + LUAL_COROCSTK;
if (L->nCcalls >= LUAI_MAXCCALLS) if (L->nCcalls >= LUAI_MAXCCALLS)
return resume_error(L, "C stack overflow", nargs); return resume_error(L, "C stack overflow", nargs);
luai_userstateresume(L, nargs); luai_userstateresume(L, nargs);