]> git.ipfire.org Git - thirdparty/LuaJIT.git/commitdiff
Merge branch 'master' into v2.1
authorMike Pall <mike>
Sun, 4 Feb 2024 15:47:14 +0000 (16:47 +0100)
committerMike Pall <mike>
Sun, 4 Feb 2024 15:47:14 +0000 (16:47 +0100)
1  2 
src/lj_debug.c
src/lj_err.c
src/lj_err.h
src/lj_state.c

diff --cc src/lj_debug.c
Simple merge
diff --cc src/lj_err.c
index 7b11e4d01cf9515215584ee3160c0634bce13546,7afe1e291eb4d120f6f97b76f4d2cd4e580f6928..414ef477a43b2ef9515982ff63d08ab8fdfeab06
@@@ -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 (curr_funcisL(L)) L->top = curr_topL(L);
 +  if (LJ_HASJIT) {
 +    TValue *base = tvref(G(L)->jit_base);
 +    if (base) L->base = base;
 +  }
 -      setframe_gc(L->base - 1, obj2gco(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 - 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);
    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 8768fefdc45310f6c9f69fb535ea3e257e5c4d1e,150409228ee2b8cb3fa64b79f23085b5202d7e85..67686cb77255ebdb99464e5abdbf52d4931084f5
@@@ -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_FUNCA_NORET void LJ_FASTCALL lj_err_run(lua_State *L);
+ LJ_FUNC_NORET void LJ_FASTCALL lj_err_stkov(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 7e4961bd04cf088979f8fc3bdace8ce7d4972096,adedb66c17653793c0e4d9a0902ac9b1facc71a9..af17e4b502bf9a2d37ed6b2f3efad2a02f2d2c2a
@@@ -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)