@@ -102,27 +102,49 @@ void lj_state_shrinkstack(lua_State *L, MSize used)
102
102
/* Try to grow stack. */
103
103
void LJ_FASTCALL lj_state_growstack (lua_State * L , MSize need )
104
104
{
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. */
109
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
150
void LJ_FASTCALL lj_state_growstack1 (lua_State * L )
0 commit comments