diff options
| author | Mike Pall <mike> | 2024-02-04 16:47:14 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2024-02-04 16:47:14 +0100 |
| commit | 0d313b243194a0b8d2399d8b549ca5a0ff234db5 (patch) | |
| tree | e483bc17d481f168e47da7042d46b7a66a1cf79c | |
| parent | 9cc2e42b17148036d7d9ef36ab7afe52df345163 (diff) | |
| parent | defe61a56751a0db5f00ff3ab7b8f45436ba74c8 (diff) | |
| download | luajit-0d313b243194a0b8d2399d8b549ca5a0ff234db5.tar.gz luajit-0d313b243194a0b8d2399d8b549ca5a0ff234db5.tar.bz2 luajit-0d313b243194a0b8d2399d8b549ca5a0ff234db5.zip | |
Merge branch 'master' into v2.1
| -rw-r--r-- | src/lj_debug.c | 1 | ||||
| -rw-r--r-- | src/lj_err.c | 23 | ||||
| -rw-r--r-- | src/lj_err.h | 1 | ||||
| -rw-r--r-- | src/lj_state.c | 58 |
4 files changed, 62 insertions, 21 deletions
diff --git a/src/lj_debug.c b/src/lj_debug.c index fa189b6e..8d8b9eb5 100644 --- a/src/lj_debug.c +++ b/src/lj_debug.c | |||
| @@ -64,6 +64,7 @@ static BCPos debug_framepc(lua_State *L, GCfunc *fn, cTValue *nextframe) | |||
| 64 | if (cf == NULL || (char *)cframe_pc(cf) == (char *)cframe_L(cf)) | 64 | if (cf == NULL || (char *)cframe_pc(cf) == (char *)cframe_L(cf)) |
| 65 | return NO_BCPOS; | 65 | return NO_BCPOS; |
| 66 | ins = cframe_pc(cf); /* Only happens during error/hook handling. */ | 66 | ins = cframe_pc(cf); /* Only happens during error/hook handling. */ |
| 67 | if (!ins) return NO_BCPOS; | ||
| 67 | } else { | 68 | } else { |
| 68 | if (frame_islua(nextframe)) { | 69 | if (frame_islua(nextframe)) { |
| 69 | ins = frame_pc(nextframe); | 70 | ins = frame_pc(nextframe); |
diff --git a/src/lj_err.c b/src/lj_err.c index 7b11e4d0..414ef477 100644 --- a/src/lj_err.c +++ b/src/lj_err.c | |||
| @@ -818,7 +818,14 @@ LJ_NOINLINE void lj_err_mem(lua_State *L) | |||
| 818 | TValue *base = tvref(G(L)->jit_base); | 818 | TValue *base = tvref(G(L)->jit_base); |
| 819 | if (base) L->base = base; | 819 | if (base) L->base = base; |
| 820 | } | 820 | } |
| 821 | if (curr_funcisL(L)) L->top = curr_topL(L); | 821 | if (curr_funcisL(L)) { |
| 822 | L->top = curr_topL(L); | ||
| 823 | if (LJ_UNLIKELY(L->top > tvref(L->maxstack))) { | ||
| 824 | /* The current Lua frame violates the stack. Replace it with a dummy. */ | ||
| 825 | L->top = L->base; | ||
| 826 | setframe_gc(L->base - 1 - LJ_FR2, obj2gco(L), LJ_TTHREAD); | ||
| 827 | } | ||
| 828 | } | ||
| 822 | setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRMEM)); | 829 | setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRMEM)); |
| 823 | lj_err_throw(L, LUA_ERRMEM); | 830 | lj_err_throw(L, LUA_ERRMEM); |
| 824 | } | 831 | } |
| @@ -879,9 +886,11 @@ LJ_NOINLINE void LJ_FASTCALL lj_err_run(lua_State *L) | |||
| 879 | { | 886 | { |
| 880 | ptrdiff_t ef = (LJ_HASJIT && tvref(G(L)->jit_base)) ? 0 : finderrfunc(L); | 887 | ptrdiff_t ef = (LJ_HASJIT && tvref(G(L)->jit_base)) ? 0 : finderrfunc(L); |
| 881 | if (ef) { | 888 | if (ef) { |
| 882 | TValue *errfunc = restorestack(L, ef); | 889 | TValue *errfunc, *top; |
| 883 | TValue *top = L->top; | 890 | lj_state_checkstack(L, LUA_MINSTACK * 2); /* Might raise new error. */ |
| 884 | lj_trace_abort(G(L)); | 891 | lj_trace_abort(G(L)); |
| 892 | errfunc = restorestack(L, ef); | ||
| 893 | top = L->top; | ||
| 885 | if (!tvisfunc(errfunc) || L->status == LUA_ERRERR) { | 894 | if (!tvisfunc(errfunc) || L->status == LUA_ERRERR) { |
| 886 | setstrV(L, top-1, lj_err_str(L, LJ_ERR_ERRERR)); | 895 | setstrV(L, top-1, lj_err_str(L, LJ_ERR_ERRERR)); |
| 887 | lj_err_throw(L, LUA_ERRERR); | 896 | lj_err_throw(L, LUA_ERRERR); |
| @@ -896,7 +905,15 @@ LJ_NOINLINE void LJ_FASTCALL lj_err_run(lua_State *L) | |||
| 896 | lj_err_throw(L, LUA_ERRRUN); | 905 | lj_err_throw(L, LUA_ERRRUN); |
| 897 | } | 906 | } |
| 898 | 907 | ||
| 908 | /* Stack overflow error. */ | ||
| 909 | void LJ_FASTCALL lj_err_stkov(lua_State *L) | ||
| 910 | { | ||
| 911 | lj_debug_addloc(L, err2msg(LJ_ERR_STKOV), L->base-1, NULL); | ||
| 912 | lj_err_run(L); | ||
| 913 | } | ||
| 914 | |||
| 899 | #if LJ_HASJIT | 915 | #if LJ_HASJIT |
| 916 | /* Rethrow error after doing a trace exit. */ | ||
| 900 | LJ_NOINLINE void LJ_FASTCALL lj_err_trace(lua_State *L, int errcode) | 917 | LJ_NOINLINE void LJ_FASTCALL lj_err_trace(lua_State *L, int errcode) |
| 901 | { | 918 | { |
| 902 | if (errcode == LUA_ERRRUN) | 919 | if (errcode == LUA_ERRRUN) |
diff --git a/src/lj_err.h b/src/lj_err.h index 8768fefd..67686cb7 100644 --- a/src/lj_err.h +++ b/src/lj_err.h | |||
| @@ -23,6 +23,7 @@ LJ_DATA const char *lj_err_allmsg; | |||
| 23 | LJ_FUNC GCstr *lj_err_str(lua_State *L, ErrMsg em); | 23 | LJ_FUNC GCstr *lj_err_str(lua_State *L, ErrMsg em); |
| 24 | LJ_FUNCA_NORET void LJ_FASTCALL lj_err_throw(lua_State *L, int errcode); | 24 | LJ_FUNCA_NORET void LJ_FASTCALL lj_err_throw(lua_State *L, int errcode); |
| 25 | LJ_FUNC_NORET void lj_err_mem(lua_State *L); | 25 | LJ_FUNC_NORET void lj_err_mem(lua_State *L); |
| 26 | LJ_FUNC_NORET void LJ_FASTCALL lj_err_stkov(lua_State *L); | ||
| 26 | LJ_FUNC_NORET void LJ_FASTCALL lj_err_run(lua_State *L); | 27 | LJ_FUNC_NORET void LJ_FASTCALL lj_err_run(lua_State *L); |
| 27 | #if LJ_HASJIT | 28 | #if LJ_HASJIT |
| 28 | LJ_FUNCA_NORET void LJ_FASTCALL lj_err_trace(lua_State *L, int errcode); | 29 | LJ_FUNCA_NORET void LJ_FASTCALL lj_err_trace(lua_State *L, int errcode); |
diff --git a/src/lj_state.c b/src/lj_state.c index 7e4961bd..af17e4b5 100644 --- a/src/lj_state.c +++ b/src/lj_state.c | |||
| @@ -102,27 +102,49 @@ void lj_state_shrinkstack(lua_State *L, MSize used) | |||
| 102 | /* Try to grow stack. */ | 102 | /* Try to grow stack. */ |
| 103 | void LJ_FASTCALL lj_state_growstack(lua_State *L, MSize need) | 103 | void LJ_FASTCALL lj_state_growstack(lua_State *L, MSize need) |
| 104 | { | 104 | { |
| 105 | MSize n; | 105 | MSize n = L->stacksize + need; |
| 106 | if (L->stacksize >= LJ_STACK_MAXEX) { | 106 | if (LJ_LIKELY(n < LJ_STACK_MAX)) { /* The stack can grow as requested. */ |
| 107 | /* 4. Throw 'error in error handling' when we are _over_ the limit. */ | 107 | if (n < 2 * L->stacksize) { /* Try to double the size. */ |
| 108 | if (L->stacksize > LJ_STACK_MAXEX) | 108 | n = 2 * L->stacksize; |
| 109 | if (n > LJ_STACK_MAX) | ||
| 110 | n = LJ_STACK_MAX; | ||
| 111 | } | ||
| 112 | resizestack(L, n); | ||
| 113 | } else { /* Request would overflow. Raise a stack overflow error. */ | ||
| 114 | if (LJ_HASJIT) { | ||
| 115 | TValue *base = tvref(G(L)->jit_base); | ||
| 116 | if (base) L->base = base; | ||
| 117 | } | ||
| 118 | if (curr_funcisL(L)) { | ||
| 119 | L->top = curr_topL(L); | ||
| 120 | if (L->top > tvref(L->maxstack)) { | ||
| 121 | /* The current Lua frame violates the stack, so replace it with a | ||
| 122 | ** dummy. This can happen when BC_IFUNCF is trying to grow the stack. | ||
| 123 | */ | ||
| 124 | L->top = L->base; | ||
| 125 | setframe_gc(L->base - 1 - LJ_FR2, obj2gco(L), LJ_TTHREAD); | ||
| 126 | } | ||
| 127 | } | ||
| 128 | if (L->stacksize <= LJ_STACK_MAXEX) { | ||
| 129 | /* An error handler might want to inspect the stack overflow error, but | ||
| 130 | ** will need some stack space to run in. We give it a stack size beyond | ||
| 131 | ** the normal limit in order to do so, then rely on lj_state_relimitstack | ||
| 132 | ** calls during unwinding to bring us back to a convential stack size. | ||
| 133 | ** The + 1 is space for the error message, and 2 * LUA_MINSTACK is for | ||
| 134 | ** the lj_state_checkstack() call in lj_err_run(). | ||
| 135 | */ | ||
| 136 | resizestack(L, LJ_STACK_MAX + 1 + 2 * LUA_MINSTACK); | ||
| 137 | lj_err_stkov(L); /* May invoke an error handler. */ | ||
| 138 | } else { | ||
| 139 | /* If we're here, then the stack overflow error handler is requesting | ||
| 140 | ** to grow the stack even further. We have no choice but to abort the | ||
| 141 | ** error handler. | ||
| 142 | */ | ||
| 143 | GCstr *em = lj_err_str(L, LJ_ERR_STKOV); /* Might OOM. */ | ||
| 144 | setstrV(L, L->top++, em); /* There is always space to push an error. */ | ||
| 109 | lj_err_throw(L, LUA_ERRERR); /* Does not invoke an error handler. */ | 145 | lj_err_throw(L, LUA_ERRERR); /* Does not invoke an error handler. */ |
| 110 | /* 1. We are _at_ the limit after the last growth. */ | ||
| 111 | if (L->status < LUA_ERRRUN) { /* 2. Throw 'stack overflow'. */ | ||
| 112 | L->status = LUA_ERRRUN; /* Prevent ending here again for pushed msg. */ | ||
| 113 | lj_err_msg(L, LJ_ERR_STKOV); /* May invoke an error handler. */ | ||
| 114 | } | 146 | } |
| 115 | /* 3. Add space (over the limit) for pushed message and error handler. */ | ||
| 116 | } | ||
| 117 | n = L->stacksize + need; | ||
| 118 | if (n > LJ_STACK_MAX) { | ||
| 119 | n += 2*LUA_MINSTACK; | ||
| 120 | } else if (n < 2*L->stacksize) { | ||
| 121 | n = 2*L->stacksize; | ||
| 122 | if (n >= LJ_STACK_MAX) | ||
| 123 | n = LJ_STACK_MAX; | ||
| 124 | } | 147 | } |
| 125 | resizestack(L, n); | ||
| 126 | } | 148 | } |
| 127 | 149 | ||
| 128 | void LJ_FASTCALL lj_state_growstack1(lua_State *L) | 150 | void LJ_FASTCALL lj_state_growstack1(lua_State *L) |
