Handle OOM error on stack resize in coroutine.resume and lua_checkstack.

Thanks to Peter Cawley. #1066
This commit is contained in:
Mike Pall 2023-09-21 04:40:48 +02:00
parent e86990f7f2
commit a5d2f70c73
4 changed files with 23 additions and 2 deletions

View File

@ -616,7 +616,10 @@ static int ffh_resume(lua_State *L, lua_State *co, int wrap)
setstrV(L, L->base-LJ_FR2, lj_err_str(L, em)); setstrV(L, L->base-LJ_FR2, lj_err_str(L, em));
return FFH_RES(2); return FFH_RES(2);
} }
lj_state_growstack(co, (MSize)(L->top - L->base)); if (lj_state_cpgrowstack(co, (MSize)(L->top - L->base)) != LUA_OK) {
cTValue *msg = --co->top;
lj_err_callermsg(L, strVdata(msg));
}
return FFH_RETRY; return FFH_RETRY;
} }

View File

@ -104,7 +104,12 @@ LUA_API int lua_checkstack(lua_State *L, int size)
if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK) { if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK) {
return 0; /* Stack overflow. */ return 0; /* Stack overflow. */
} else if (size > 0) { } else if (size > 0) {
lj_state_checkstack(L, (MSize)size); int avail = (int)(mref(L->maxstack, TValue) - L->top);
if (size > avail &&
lj_state_cpgrowstack(L, (MSize)(size - avail)) != LUA_OK) {
L->top--;
return 0; /* Out of memory. */
}
} }
return 1; return 1;
} }

View File

@ -130,6 +130,18 @@ void LJ_FASTCALL lj_state_growstack1(lua_State *L)
lj_state_growstack(L, 1); lj_state_growstack(L, 1);
} }
static TValue *cpgrowstack(lua_State *co, lua_CFunction dummy, void *ud)
{
UNUSED(dummy);
lj_state_growstack(co, *(MSize *)ud);
return NULL;
}
int LJ_FASTCALL lj_state_cpgrowstack(lua_State *L, MSize need)
{
return lj_vm_cpcall(L, NULL, &need, cpgrowstack);
}
/* Allocate basic stack for new state. */ /* Allocate basic stack for new state. */
static void stack_init(lua_State *L1, lua_State *L) static void stack_init(lua_State *L1, lua_State *L)
{ {

View File

@ -18,6 +18,7 @@ LJ_FUNC void lj_state_relimitstack(lua_State *L);
LJ_FUNC void lj_state_shrinkstack(lua_State *L, MSize used); LJ_FUNC void lj_state_shrinkstack(lua_State *L, MSize used);
LJ_FUNCA void LJ_FASTCALL lj_state_growstack(lua_State *L, MSize need); LJ_FUNCA void LJ_FASTCALL lj_state_growstack(lua_State *L, MSize need);
LJ_FUNC void LJ_FASTCALL lj_state_growstack1(lua_State *L); LJ_FUNC void LJ_FASTCALL lj_state_growstack1(lua_State *L);
LJ_FUNC int LJ_FASTCALL lj_state_cpgrowstack(lua_State *L, MSize need);
static LJ_AINLINE void lj_state_checkstack(lua_State *L, MSize need) static LJ_AINLINE void lj_state_checkstack(lua_State *L, MSize need)
{ {