aboutsummaryrefslogtreecommitdiff
path: root/src/lj_state.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lj_state.c54
1 files changed, 36 insertions, 18 deletions
diff --git a/src/lj_state.c b/src/lj_state.c
index c2f0b115..adedb66c 100644
--- a/src/lj_state.c
+++ b/src/lj_state.c
@@ -96,27 +96,45 @@ void lj_state_shrinkstack(lua_State *L, MSize used)
96/* Try to grow stack. */ 96/* Try to grow stack. */
97void LJ_FASTCALL lj_state_growstack(lua_State *L, MSize need) 97void LJ_FASTCALL lj_state_growstack(lua_State *L, MSize need)
98{ 98{
99 MSize n; 99 MSize n = L->stacksize + need;
100 if (L->stacksize >= LJ_STACK_MAXEX) { 100 if (LJ_LIKELY(n < LJ_STACK_MAX)) { /* The stack can grow as requested. */
101 /* 4. Throw 'error in error handling' when we are _over_ the limit. */ 101 if (n < 2 * L->stacksize) { /* Try to double the size. */
102 if (L->stacksize > LJ_STACK_MAXEX) 102 n = 2 * L->stacksize;
103 if (n > LJ_STACK_MAX)
104 n = LJ_STACK_MAX;
105 }
106 resizestack(L, n);
107 } else { /* Request would overflow. Raise a stack overflow error. */
108 if (curr_funcisL(L)) {
109 L->top = curr_topL(L);
110 if (L->top > tvref(L->maxstack)) {
111 /* The current Lua frame violates the stack, so replace it with a
112 ** dummy. This can happen when BC_IFUNCF is trying to grow the stack.
113 */
114 L->top = L->base;
115 setframe_gc(L->base - 1, obj2gco(L));
116 }
117 }
118 if (L->stacksize <= LJ_STACK_MAXEX) {
119 /* An error handler might want to inspect the stack overflow error, but
120 ** will need some stack space to run in. We give it a stack size beyond
121 ** the normal limit in order to do so, then rely on lj_state_relimitstack
122 ** calls during unwinding to bring us back to a convential stack size.
123 ** The + 1 is space for the error message, and 2 * LUA_MINSTACK is for
124 ** the lj_state_checkstack() call in lj_err_run().
125 */
126 resizestack(L, LJ_STACK_MAX + 1 + 2 * LUA_MINSTACK);
127 lj_err_stkov(L); /* May invoke an error handler. */
128 } else {
129 /* If we're here, then the stack overflow error handler is requesting
130 ** to grow the stack even further. We have no choice but to abort the
131 ** error handler.
132 */
133 GCstr *em = lj_err_str(L, LJ_ERR_STKOV); /* Might OOM. */
134 setstrV(L, L->top++, em); /* There is always space to push an error. */
103 lj_err_throw(L, LUA_ERRERR); /* Does not invoke an error handler. */ 135 lj_err_throw(L, LUA_ERRERR); /* Does not invoke an error handler. */
104 /* 1. We are _at_ the limit after the last growth. */
105 if (L->status < LUA_ERRRUN) { /* 2. Throw 'stack overflow'. */
106 L->status = LUA_ERRRUN; /* Prevent ending here again for pushed msg. */
107 lj_err_msg(L, LJ_ERR_STKOV); /* May invoke an error handler. */
108 } 136 }
109 /* 3. Add space (over the limit) for pushed message and error handler. */
110 }
111 n = L->stacksize + need;
112 if (n > LJ_STACK_MAX) {
113 n += 2*LUA_MINSTACK;
114 } else if (n < 2*L->stacksize) {
115 n = 2*L->stacksize;
116 if (n >= LJ_STACK_MAX)
117 n = LJ_STACK_MAX;
118 } 137 }
119 resizestack(L, n);
120} 138}
121 139
122void LJ_FASTCALL lj_state_growstack1(lua_State *L) 140void LJ_FASTCALL lj_state_growstack1(lua_State *L)