From: Mike Pall Date: Sun, 4 Feb 2024 15:47:14 +0000 (+0100) Subject: Merge branch 'master' into v2.1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0d313b243194a0b8d2399d8b549ca5a0ff234db5;p=thirdparty%2FLuaJIT.git Merge branch 'master' into v2.1 --- 0d313b243194a0b8d2399d8b549ca5a0ff234db5 diff --cc src/lj_err.c index 7b11e4d0,7afe1e29..414ef477 --- a/src/lj_err.c +++ b/src/lj_err.c @@@ -814,11 -488,14 +814,18 @@@ LJ_NOINLINE void lj_err_mem(lua_State * { if (L->status == LUA_ERRERR+1) /* Don't touch the stack during lua_open. */ lj_vm_unwind_c(L->cframe, LUA_ERRMEM); + if (LJ_HASJIT) { + TValue *base = tvref(G(L)->jit_base); + if (base) L->base = base; + } - if (curr_funcisL(L)) L->top = curr_topL(L); + if (curr_funcisL(L)) { + L->top = curr_topL(L); + if (LJ_UNLIKELY(L->top > tvref(L->maxstack))) { + /* The current Lua frame violates the stack. Replace it with a dummy. */ + L->top = L->base; - setframe_gc(L->base - 1, obj2gco(L)); ++ setframe_gc(L->base - 1 - LJ_FR2, obj2gco(L), LJ_TTHREAD); + } + } setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRMEM)); lj_err_throw(L, LUA_ERRMEM); } @@@ -877,11 -556,13 +884,13 @@@ static ptrdiff_t finderrfunc(lua_State /* Runtime error. */ LJ_NOINLINE void LJ_FASTCALL lj_err_run(lua_State *L) { - ptrdiff_t ef = finderrfunc(L); + ptrdiff_t ef = (LJ_HASJIT && tvref(G(L)->jit_base)) ? 0 : finderrfunc(L); if (ef) { - TValue *errfunc = restorestack(L, ef); - TValue *top = L->top; + TValue *errfunc, *top; + lj_state_checkstack(L, LUA_MINSTACK * 2); /* Might raise new error. */ lj_trace_abort(G(L)); + errfunc = restorestack(L, ef); + top = L->top; if (!tvisfunc(errfunc) || L->status == LUA_ERRERR) { setstrV(L, top-1, lj_err_str(L, LJ_ERR_ERRERR)); lj_err_throw(L, LUA_ERRERR); @@@ -896,16 -576,13 +905,24 @@@ lj_err_throw(L, LUA_ERRRUN); } + /* Stack overflow error. */ + void LJ_FASTCALL lj_err_stkov(lua_State *L) + { + lj_debug_addloc(L, err2msg(LJ_ERR_STKOV), L->base-1, NULL); + lj_err_run(L); + } + +#if LJ_HASJIT ++/* Rethrow error after doing a trace exit. */ +LJ_NOINLINE void LJ_FASTCALL lj_err_trace(lua_State *L, int errcode) +{ + if (errcode == LUA_ERRRUN) + lj_err_run(L); + else + lj_err_throw(L, errcode); +} +#endif + /* Formatted runtime error message. */ LJ_NORET LJ_NOINLINE static void err_msgv(lua_State *L, ErrMsg em, ...) { diff --cc src/lj_err.h index 8768fefd,15040922..67686cb7 --- a/src/lj_err.h +++ b/src/lj_err.h @@@ -23,10 -23,8 +23,11 @@@ LJ_DATA const char *lj_err_allmsg LJ_FUNC GCstr *lj_err_str(lua_State *L, ErrMsg em); LJ_FUNCA_NORET void LJ_FASTCALL lj_err_throw(lua_State *L, int errcode); LJ_FUNC_NORET void lj_err_mem(lua_State *L); + LJ_FUNC_NORET void LJ_FASTCALL lj_err_stkov(lua_State *L); -LJ_FUNCA_NORET void LJ_FASTCALL lj_err_run(lua_State *L); +LJ_FUNC_NORET void LJ_FASTCALL lj_err_run(lua_State *L); +#if LJ_HASJIT +LJ_FUNCA_NORET void LJ_FASTCALL lj_err_trace(lua_State *L, int errcode); +#endif LJ_FUNC_NORET void lj_err_msg(lua_State *L, ErrMsg em); LJ_FUNC_NORET void lj_err_lex(lua_State *L, GCstr *src, const char *tok, BCLine line, ErrMsg em, va_list argp); diff --cc src/lj_state.c index 7e4961bd,adedb66c..af17e4b5 --- a/src/lj_state.c +++ b/src/lj_state.c @@@ -102,27 -96,45 +102,49 @@@ void lj_state_shrinkstack(lua_State *L /* Try to grow stack. */ void LJ_FASTCALL lj_state_growstack(lua_State *L, MSize need) { - MSize n; - if (L->stacksize >= LJ_STACK_MAXEX) { - /* 4. Throw 'error in error handling' when we are _over_ the limit. */ - if (L->stacksize > LJ_STACK_MAXEX) + MSize n = L->stacksize + need; + if (LJ_LIKELY(n < LJ_STACK_MAX)) { /* The stack can grow as requested. */ + if (n < 2 * L->stacksize) { /* Try to double the size. */ + n = 2 * L->stacksize; + if (n > LJ_STACK_MAX) + n = LJ_STACK_MAX; + } + resizestack(L, n); + } else { /* Request would overflow. Raise a stack overflow error. */ ++ if (LJ_HASJIT) { ++ TValue *base = tvref(G(L)->jit_base); ++ if (base) L->base = base; ++ } + if (curr_funcisL(L)) { + L->top = curr_topL(L); + if (L->top > tvref(L->maxstack)) { + /* The current Lua frame violates the stack, so replace it with a + ** dummy. This can happen when BC_IFUNCF is trying to grow the stack. + */ + L->top = L->base; - setframe_gc(L->base - 1, obj2gco(L)); ++ setframe_gc(L->base - 1 - LJ_FR2, obj2gco(L), LJ_TTHREAD); + } + } + if (L->stacksize <= LJ_STACK_MAXEX) { + /* An error handler might want to inspect the stack overflow error, but + ** will need some stack space to run in. We give it a stack size beyond + ** the normal limit in order to do so, then rely on lj_state_relimitstack + ** calls during unwinding to bring us back to a convential stack size. + ** The + 1 is space for the error message, and 2 * LUA_MINSTACK is for + ** the lj_state_checkstack() call in lj_err_run(). + */ + resizestack(L, LJ_STACK_MAX + 1 + 2 * LUA_MINSTACK); + lj_err_stkov(L); /* May invoke an error handler. */ + } else { + /* If we're here, then the stack overflow error handler is requesting + ** to grow the stack even further. We have no choice but to abort the + ** error handler. + */ + GCstr *em = lj_err_str(L, LJ_ERR_STKOV); /* Might OOM. */ + setstrV(L, L->top++, em); /* There is always space to push an error. */ lj_err_throw(L, LUA_ERRERR); /* Does not invoke an error handler. */ - /* 1. We are _at_ the limit after the last growth. */ - if (L->status < LUA_ERRRUN) { /* 2. Throw 'stack overflow'. */ - L->status = LUA_ERRRUN; /* Prevent ending here again for pushed msg. */ - lj_err_msg(L, LJ_ERR_STKOV); /* May invoke an error handler. */ } - /* 3. Add space (over the limit) for pushed message and error handler. */ - } - n = L->stacksize + need; - if (n > LJ_STACK_MAX) { - n += 2*LUA_MINSTACK; - } else if (n < 2*L->stacksize) { - n = 2*L->stacksize; - if (n >= LJ_STACK_MAX) - n = LJ_STACK_MAX; } - resizestack(L, n); } void LJ_FASTCALL lj_state_growstack1(lua_State *L)