aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2024-02-04 16:47:14 +0100
committerMike Pall <mike>2024-02-04 16:47:14 +0100
commit0d313b243194a0b8d2399d8b549ca5a0ff234db5 (patch)
treee483bc17d481f168e47da7042d46b7a66a1cf79c /src
parent9cc2e42b17148036d7d9ef36ab7afe52df345163 (diff)
parentdefe61a56751a0db5f00ff3ab7b8f45436ba74c8 (diff)
downloadluajit-0d313b243194a0b8d2399d8b549ca5a0ff234db5.tar.gz
luajit-0d313b243194a0b8d2399d8b549ca5a0ff234db5.tar.bz2
luajit-0d313b243194a0b8d2399d8b549ca5a0ff234db5.zip
Merge branch 'master' into v2.1
Diffstat (limited to 'src')
-rw-r--r--src/lj_debug.c1
-rw-r--r--src/lj_err.c23
-rw-r--r--src/lj_err.h1
-rw-r--r--src/lj_state.c58
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. */
909void 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. */
900LJ_NOINLINE void LJ_FASTCALL lj_err_trace(lua_State *L, int errcode) 917LJ_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;
23LJ_FUNC GCstr *lj_err_str(lua_State *L, ErrMsg em); 23LJ_FUNC GCstr *lj_err_str(lua_State *L, ErrMsg em);
24LJ_FUNCA_NORET void LJ_FASTCALL lj_err_throw(lua_State *L, int errcode); 24LJ_FUNCA_NORET void LJ_FASTCALL lj_err_throw(lua_State *L, int errcode);
25LJ_FUNC_NORET void lj_err_mem(lua_State *L); 25LJ_FUNC_NORET void lj_err_mem(lua_State *L);
26LJ_FUNC_NORET void LJ_FASTCALL lj_err_stkov(lua_State *L);
26LJ_FUNC_NORET void LJ_FASTCALL lj_err_run(lua_State *L); 27LJ_FUNC_NORET void LJ_FASTCALL lj_err_run(lua_State *L);
27#if LJ_HASJIT 28#if LJ_HASJIT
28LJ_FUNCA_NORET void LJ_FASTCALL lj_err_trace(lua_State *L, int errcode); 29LJ_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. */
103void LJ_FASTCALL lj_state_growstack(lua_State *L, MSize need) 103void 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
128void LJ_FASTCALL lj_state_growstack1(lua_State *L) 150void LJ_FASTCALL lj_state_growstack1(lua_State *L)