|
@@ -138,7 +138,7 @@ l_noret luaD_throw (lua_State *L, int errcode) {
|
|
|
|
|
|
|
|
|
|
int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
|
|
int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
|
|
- unsigned short oldnCcalls = L->nCcalls - L->nci;
|
|
|
|
|
|
+ l_uint32 oldnCcalls = L->nCcalls - L->nci;
|
|
struct lua_longjmp lj;
|
|
struct lua_longjmp lj;
|
|
lua_assert(L->nCcalls >= L->nci);
|
|
lua_assert(L->nCcalls >= L->nci);
|
|
lj.status = LUA_OK;
|
|
lj.status = LUA_OK;
|
|
@@ -513,12 +513,17 @@ void luaD_call (lua_State *L, StkId func, int nresults) {
|
|
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
-** Similar to 'luaD_call', but does not allow yields during the call
|
|
|
|
|
|
+** Similar to 'luaD_call', but does not allow yields during the call.
|
|
|
|
+** If there is a stack overflow, freeing all CI structures will
|
|
|
|
+** force the subsequent call to invoke 'luaE_extendCI', which then
|
|
|
|
+** will raise any errors.
|
|
*/
|
|
*/
|
|
void luaD_callnoyield (lua_State *L, StkId func, int nResults) {
|
|
void luaD_callnoyield (lua_State *L, StkId func, int nResults) {
|
|
- L->nny++;
|
|
|
|
|
|
+ incXCcalls(L);
|
|
|
|
+ if (getCcalls(L) >= LUAI_MAXCCALLS) /* possible stack overflow? */
|
|
|
|
+ luaE_freeCI(L);
|
|
luaD_call(L, func, nResults);
|
|
luaD_call(L, func, nResults);
|
|
- L->nny--;
|
|
|
|
|
|
+ decXCcalls(L);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -530,7 +535,7 @@ static void finishCcall (lua_State *L, int status) {
|
|
CallInfo *ci = L->ci;
|
|
CallInfo *ci = L->ci;
|
|
int n;
|
|
int n;
|
|
/* must have a continuation and must be able to call it */
|
|
/* must have a continuation and must be able to call it */
|
|
- lua_assert(ci->u.c.k != NULL && L->nny == 0);
|
|
|
|
|
|
+ lua_assert(ci->u.c.k != NULL && yieldable(L));
|
|
/* error status can only happen in a protected call */
|
|
/* error status can only happen in a protected call */
|
|
lua_assert((ci->callstatus & CIST_YPCALL) || status == LUA_YIELD);
|
|
lua_assert((ci->callstatus & CIST_YPCALL) || status == LUA_YIELD);
|
|
if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */
|
|
if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */
|
|
@@ -601,7 +606,6 @@ static int recover (lua_State *L, int status) {
|
|
luaD_seterrorobj(L, status, oldtop);
|
|
luaD_seterrorobj(L, status, oldtop);
|
|
L->ci = ci;
|
|
L->ci = ci;
|
|
L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */
|
|
L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */
|
|
- L->nny = 0; /* should be zero to be yieldable */
|
|
|
|
luaD_shrinkstack(L);
|
|
luaD_shrinkstack(L);
|
|
L->errfunc = ci->u.c.old_errfunc;
|
|
L->errfunc = ci->u.c.old_errfunc;
|
|
return 1; /* continue running the coroutine */
|
|
return 1; /* continue running the coroutine */
|
|
@@ -622,13 +626,6 @@ 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
|
|
@@ -664,7 +661,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;
|
|
- unsigned short oldnny = L->nny; /* save "number of non-yieldable" calls */
|
|
|
|
lua_lock(L);
|
|
lua_lock(L);
|
|
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? */
|
|
@@ -675,11 +671,10 @@ 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 + LUAL_COROCSTK;
|
|
|
|
|
|
+ L->nCcalls = getCcalls(from) - from->nci + L->nci + CSTACKCF;
|
|
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);
|
|
- L->nny = 0; /* allow yields */
|
|
|
|
api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
|
|
api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
|
|
status = luaD_rawrunprotected(L, resume, &nargs);
|
|
status = luaD_rawrunprotected(L, resume, &nargs);
|
|
/* continue running after recoverable errors */
|
|
/* continue running after recoverable errors */
|
|
@@ -698,14 +693,13 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs,
|
|
}
|
|
}
|
|
*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 - (L->ci->func + 1));
|
|
- L->nny = oldnny; /* restore 'nny' */
|
|
|
|
lua_unlock(L);
|
|
lua_unlock(L);
|
|
return status;
|
|
return status;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
LUA_API int lua_isyieldable (lua_State *L) {
|
|
LUA_API int lua_isyieldable (lua_State *L) {
|
|
- return (L->nny == 0);
|
|
|
|
|
|
+ return yieldable(L);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -715,7 +709,7 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
|
|
luai_userstateyield(L, nresults);
|
|
luai_userstateyield(L, nresults);
|
|
lua_lock(L);
|
|
lua_lock(L);
|
|
api_checknelems(L, nresults);
|
|
api_checknelems(L, nresults);
|
|
- if (unlikely(L->nny > 0)) {
|
|
|
|
|
|
+ if (unlikely(!yieldable(L))) {
|
|
if (L != G(L)->mainthread)
|
|
if (L != G(L)->mainthread)
|
|
luaG_runerror(L, "attempt to yield across a C-call boundary");
|
|
luaG_runerror(L, "attempt to yield across a C-call boundary");
|
|
else
|
|
else
|
|
@@ -741,7 +735,7 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
|
|
|
|
|
|
/*
|
|
/*
|
|
** Call the C function 'func' in protected mode, restoring basic
|
|
** Call the C function 'func' in protected mode, restoring basic
|
|
-** thread information ('allowhook', 'nny', etc.) and in particular
|
|
|
|
|
|
+** thread information ('allowhook', etc.) and in particular
|
|
** its stack level in case of errors.
|
|
** its stack level in case of errors.
|
|
*/
|
|
*/
|
|
int luaD_pcall (lua_State *L, Pfunc func, void *u,
|
|
int luaD_pcall (lua_State *L, Pfunc func, void *u,
|
|
@@ -749,7 +743,6 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u,
|
|
int status;
|
|
int status;
|
|
CallInfo *old_ci = L->ci;
|
|
CallInfo *old_ci = L->ci;
|
|
lu_byte old_allowhooks = L->allowhook;
|
|
lu_byte old_allowhooks = L->allowhook;
|
|
- unsigned short old_nny = L->nny;
|
|
|
|
ptrdiff_t old_errfunc = L->errfunc;
|
|
ptrdiff_t old_errfunc = L->errfunc;
|
|
L->errfunc = ef;
|
|
L->errfunc = ef;
|
|
status = luaD_rawrunprotected(L, func, u);
|
|
status = luaD_rawrunprotected(L, func, u);
|
|
@@ -757,7 +750,6 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u,
|
|
StkId oldtop = restorestack(L, old_top);
|
|
StkId oldtop = restorestack(L, old_top);
|
|
L->ci = old_ci;
|
|
L->ci = old_ci;
|
|
L->allowhook = old_allowhooks;
|
|
L->allowhook = old_allowhooks;
|
|
- L->nny = old_nny;
|
|
|
|
status = luaF_close(L, oldtop, status);
|
|
status = luaF_close(L, oldtop, status);
|
|
oldtop = restorestack(L, old_top); /* previous call may change stack */
|
|
oldtop = restorestack(L, old_top); /* previous call may change stack */
|
|
luaD_seterrorobj(L, status, oldtop);
|
|
luaD_seterrorobj(L, status, oldtop);
|
|
@@ -811,7 +803,7 @@ int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
|
|
const char *mode) {
|
|
const char *mode) {
|
|
struct SParser p;
|
|
struct SParser p;
|
|
int status;
|
|
int status;
|
|
- L->nny++; /* cannot yield during parsing */
|
|
|
|
|
|
+ incnny(L); /* cannot yield during parsing */
|
|
p.z = z; p.name = name; p.mode = mode;
|
|
p.z = z; p.name = name; p.mode = mode;
|
|
p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0;
|
|
p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0;
|
|
p.dyd.gt.arr = NULL; p.dyd.gt.size = 0;
|
|
p.dyd.gt.arr = NULL; p.dyd.gt.size = 0;
|
|
@@ -822,7 +814,7 @@ int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
|
|
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);
|
|
luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size);
|
|
luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size);
|
|
- L->nny--;
|
|
|
|
|
|
+ decnny(L);
|
|
return status;
|
|
return status;
|
|
}
|
|
}
|
|
|
|
|