Skip to content

Commit 0d313b2

Browse files
author
Mike Pall
committed
Merge branch 'master' into v2.1
2 parents 9cc2e42 + defe61a commit 0d313b2

File tree

4 files changed

+62
-21
lines changed

4 files changed

+62
-21
lines changed

src/lj_debug.c

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ static BCPos debug_framepc(lua_State *L, GCfunc *fn, cTValue *nextframe)
6464
if (cf == NULL || (char *)cframe_pc(cf) == (char *)cframe_L(cf))
6565
return NO_BCPOS;
6666
ins = cframe_pc(cf); /* Only happens during error/hook handling. */
67+
if (!ins) return NO_BCPOS;
6768
} else {
6869
if (frame_islua(nextframe)) {
6970
ins = frame_pc(nextframe);

src/lj_err.c

+20-3
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,14 @@ LJ_NOINLINE void lj_err_mem(lua_State *L)
818818
TValue *base = tvref(G(L)->jit_base);
819819
if (base) L->base = base;
820820
}
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+
}
822829
setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRMEM));
823830
lj_err_throw(L, LUA_ERRMEM);
824831
}
@@ -879,9 +886,11 @@ LJ_NOINLINE void LJ_FASTCALL lj_err_run(lua_State *L)
879886
{
880887
ptrdiff_t ef = (LJ_HASJIT && tvref(G(L)->jit_base)) ? 0 : finderrfunc(L);
881888
if (ef) {
882-
TValue *errfunc = restorestack(L, ef);
883-
TValue *top = L->top;
889+
TValue *errfunc, *top;
890+
lj_state_checkstack(L, LUA_MINSTACK * 2); /* Might raise new error. */
884891
lj_trace_abort(G(L));
892+
errfunc = restorestack(L, ef);
893+
top = L->top;
885894
if (!tvisfunc(errfunc) || L->status == LUA_ERRERR) {
886895
setstrV(L, top-1, lj_err_str(L, LJ_ERR_ERRERR));
887896
lj_err_throw(L, LUA_ERRERR);
@@ -896,7 +905,15 @@ LJ_NOINLINE void LJ_FASTCALL lj_err_run(lua_State *L)
896905
lj_err_throw(L, LUA_ERRRUN);
897906
}
898907

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+
899915
#if LJ_HASJIT
916+
/* Rethrow error after doing a trace exit. */
900917
LJ_NOINLINE void LJ_FASTCALL lj_err_trace(lua_State *L, int errcode)
901918
{
902919
if (errcode == LUA_ERRRUN)

src/lj_err.h

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ LJ_DATA const char *lj_err_allmsg;
2323
LJ_FUNC GCstr *lj_err_str(lua_State *L, ErrMsg em);
2424
LJ_FUNCA_NORET void LJ_FASTCALL lj_err_throw(lua_State *L, int errcode);
2525
LJ_FUNC_NORET void lj_err_mem(lua_State *L);
26+
LJ_FUNC_NORET void LJ_FASTCALL lj_err_stkov(lua_State *L);
2627
LJ_FUNC_NORET void LJ_FASTCALL lj_err_run(lua_State *L);
2728
#if LJ_HASJIT
2829
LJ_FUNCA_NORET void LJ_FASTCALL lj_err_trace(lua_State *L, int errcode);

src/lj_state.c

+40-18
Original file line numberDiff line numberDiff line change
@@ -102,27 +102,49 @@ void lj_state_shrinkstack(lua_State *L, MSize used)
102102
/* Try to grow stack. */
103103
void LJ_FASTCALL lj_state_growstack(lua_State *L, MSize need)
104104
{
105-
MSize n;
106-
if (L->stacksize >= LJ_STACK_MAXEX) {
107-
/* 4. Throw 'error in error handling' when we are _over_ the limit. */
108-
if (L->stacksize > LJ_STACK_MAXEX)
105+
MSize n = L->stacksize + need;
106+
if (LJ_LIKELY(n < LJ_STACK_MAX)) { /* The stack can grow as requested. */
107+
if (n < 2 * L->stacksize) { /* Try to double the size. */
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. */
109145
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. */
114146
}
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;
124147
}
125-
resizestack(L, n);
126148
}
127149

128150
void LJ_FASTCALL lj_state_growstack1(lua_State *L)

0 commit comments

Comments
 (0)