diff options
-rw-r--r-- | ldo.c | 19 | ||||
-rw-r--r-- | lgc.c | 5 | ||||
-rw-r--r-- | lstate.c | 8 | ||||
-rw-r--r-- | lstate.h | 13 | ||||
-rw-r--r-- | ltests.c | 8 | ||||
-rw-r--r-- | lvm.c | 2 |
6 files changed, 29 insertions, 26 deletions
@@ -182,10 +182,10 @@ static void correctstack (lua_State *L, StkId oldstack, StkId newstack) { | |||
182 | 182 | ||
183 | 183 | ||
184 | int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) { | 184 | int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) { |
185 | int lim = L->stacksize; | 185 | int lim = stacksize(L); |
186 | StkId newstack = luaM_reallocvector(L, L->stack, lim, newsize, StackValue); | 186 | StkId newstack = luaM_reallocvector(L, L->stack, |
187 | lim + EXTRA_STACK, newsize + EXTRA_STACK, StackValue); | ||
187 | lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE); | 188 | lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE); |
188 | lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK); | ||
189 | if (unlikely(newstack == NULL)) { /* reallocation failed? */ | 189 | if (unlikely(newstack == NULL)) { /* reallocation failed? */ |
190 | if (raiseerror) | 190 | if (raiseerror) |
191 | luaM_error(L); | 191 | luaM_error(L); |
@@ -195,8 +195,7 @@ int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) { | |||
195 | setnilvalue(s2v(newstack + lim)); /* erase new segment */ | 195 | setnilvalue(s2v(newstack + lim)); /* erase new segment */ |
196 | correctstack(L, L->stack, newstack); | 196 | correctstack(L, L->stack, newstack); |
197 | L->stack = newstack; | 197 | L->stack = newstack; |
198 | L->stacksize = newsize; | 198 | L->stack_last = L->stack + newsize; |
199 | L->stack_last = L->stack + newsize - EXTRA_STACK; | ||
200 | return 1; | 199 | return 1; |
201 | } | 200 | } |
202 | 201 | ||
@@ -206,19 +205,19 @@ int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) { | |||
206 | ** is true, raises any error; otherwise, return 0 in case of errors. | 205 | ** is true, raises any error; otherwise, return 0 in case of errors. |
207 | */ | 206 | */ |
208 | int luaD_growstack (lua_State *L, int n, int raiseerror) { | 207 | int luaD_growstack (lua_State *L, int n, int raiseerror) { |
209 | int size = L->stacksize; | 208 | int size = stacksize(L); |
210 | if (unlikely(size > LUAI_MAXSTACK)) { | 209 | if (unlikely(size > LUAI_MAXSTACK)) { |
211 | /* if stack is larger than maximum, thread is already using the | 210 | /* if stack is larger than maximum, thread is already using the |
212 | extra space reserved for errors, that is, thread is handling | 211 | extra space reserved for errors, that is, thread is handling |
213 | a stack error; cannot grow further than that. */ | 212 | a stack error; cannot grow further than that. */ |
214 | lua_assert(L->stacksize == ERRORSTACKSIZE); | 213 | lua_assert(stacksize(L) == ERRORSTACKSIZE); |
215 | if (raiseerror) | 214 | if (raiseerror) |
216 | luaD_throw(L, LUA_ERRERR); /* error inside message handler */ | 215 | luaD_throw(L, LUA_ERRERR); /* error inside message handler */ |
217 | return 0; /* if not 'raiseerror', just signal it */ | 216 | return 0; /* if not 'raiseerror', just signal it */ |
218 | } | 217 | } |
219 | else { | 218 | else { |
220 | int newsize = 2 * size; /* tentative new size */ | 219 | int newsize = 2 * size; /* tentative new size */ |
221 | int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK; | 220 | int needed = cast_int(L->top - L->stack) + n; |
222 | if (newsize > LUAI_MAXSTACK) /* cannot cross the limit */ | 221 | if (newsize > LUAI_MAXSTACK) /* cannot cross the limit */ |
223 | newsize = LUAI_MAXSTACK; | 222 | newsize = LUAI_MAXSTACK; |
224 | if (newsize < needed) /* but must respect what was asked for */ | 223 | if (newsize < needed) /* but must respect what was asked for */ |
@@ -257,7 +256,7 @@ static int stackinuse (lua_State *L) { | |||
257 | ** previous size, and half of its entries are empty.) | 256 | ** previous size, and half of its entries are empty.) |
258 | ** As a particular case, if stack was handling a stack overflow and now | 257 | ** As a particular case, if stack was handling a stack overflow and now |
259 | ** it is not, 'max' (limited by LUAI_MAXSTACK) will be smaller than | 258 | ** it is not, 'max' (limited by LUAI_MAXSTACK) will be smaller than |
260 | ** 'stacksize' (equal to ERRORSTACKSIZE in this case), and so the stack | 259 | ** stacksize (equal to ERRORSTACKSIZE in this case), and so the stack |
261 | ** will be reduced to a "regular" size. | 260 | ** will be reduced to a "regular" size. |
262 | */ | 261 | */ |
263 | void luaD_shrinkstack (lua_State *L) { | 262 | void luaD_shrinkstack (lua_State *L) { |
@@ -271,7 +270,7 @@ void luaD_shrinkstack (lua_State *L) { | |||
271 | } | 270 | } |
272 | /* if thread is currently not handling a stack overflow and its | 271 | /* if thread is currently not handling a stack overflow and its |
273 | size is larger than maximum "reasonable" size, shrink it */ | 272 | size is larger than maximum "reasonable" size, shrink it */ |
274 | if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) && L->stacksize > max) | 273 | if (inuse <= LUAI_MAXSTACK && stacksize(L) > max) |
275 | luaD_reallocstack(L, nsize, 0); /* ok if that fails */ | 274 | luaD_reallocstack(L, nsize, 0); /* ok if that fails */ |
276 | else /* don't change stack */ | 275 | else /* don't change stack */ |
277 | condmovestack(L,{},{}); /* (change only for debugging) */ | 276 | condmovestack(L,{},{}); /* (change only for debugging) */ |
@@ -633,8 +633,7 @@ static int traversethread (global_State *g, lua_State *th) { | |||
633 | for (uv = th->openupval; uv != NULL; uv = uv->u.open.next) | 633 | for (uv = th->openupval; uv != NULL; uv = uv->u.open.next) |
634 | markobject(g, uv); /* open upvalues cannot be collected */ | 634 | markobject(g, uv); /* open upvalues cannot be collected */ |
635 | if (g->gcstate == GCSatomic) { /* final traversal? */ | 635 | if (g->gcstate == GCSatomic) { /* final traversal? */ |
636 | StkId lim = th->stack + th->stacksize; /* real end of stack */ | 636 | for (; o < th->stack_last; o++) /* clear not-marked stack slice */ |
637 | for (; o < lim; o++) /* clear not-marked stack slice */ | ||
638 | setnilvalue(s2v(o)); | 637 | setnilvalue(s2v(o)); |
639 | /* 'remarkupvals' may have removed thread from 'twups' list */ | 638 | /* 'remarkupvals' may have removed thread from 'twups' list */ |
640 | if (!isintwups(th) && th->openupval != NULL) { | 639 | if (!isintwups(th) && th->openupval != NULL) { |
@@ -644,7 +643,7 @@ static int traversethread (global_State *g, lua_State *th) { | |||
644 | } | 643 | } |
645 | else if (!g->gcemergency) | 644 | else if (!g->gcemergency) |
646 | luaD_shrinkstack(th); /* do not change stack in emergency cycle */ | 645 | luaD_shrinkstack(th); /* do not change stack in emergency cycle */ |
647 | return 1 + th->stacksize; | 646 | return 1 + stacksize(th); |
648 | } | 647 | } |
649 | 648 | ||
650 | 649 | ||
@@ -180,12 +180,11 @@ LUAI_FUNC void luaE_incCstack (lua_State *L) { | |||
180 | static void stack_init (lua_State *L1, lua_State *L) { | 180 | static void stack_init (lua_State *L1, lua_State *L) { |
181 | int i; CallInfo *ci; | 181 | int i; CallInfo *ci; |
182 | /* initialize stack array */ | 182 | /* initialize stack array */ |
183 | L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, StackValue); | 183 | L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, StackValue); |
184 | L1->stacksize = BASIC_STACK_SIZE; | ||
185 | for (i = 0; i < BASIC_STACK_SIZE; i++) | 184 | for (i = 0; i < BASIC_STACK_SIZE; i++) |
186 | setnilvalue(s2v(L1->stack + i)); /* erase new stack */ | 185 | setnilvalue(s2v(L1->stack + i)); /* erase new stack */ |
187 | L1->top = L1->stack; | 186 | L1->top = L1->stack; |
188 | L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK; | 187 | L1->stack_last = L1->stack + BASIC_STACK_SIZE; |
189 | /* initialize first ci */ | 188 | /* initialize first ci */ |
190 | ci = &L1->base_ci; | 189 | ci = &L1->base_ci; |
191 | ci->next = ci->previous = NULL; | 190 | ci->next = ci->previous = NULL; |
@@ -206,7 +205,7 @@ static void freestack (lua_State *L) { | |||
206 | L->ci = &L->base_ci; /* free the entire 'ci' list */ | 205 | L->ci = &L->base_ci; /* free the entire 'ci' list */ |
207 | luaE_freeCI(L); | 206 | luaE_freeCI(L); |
208 | lua_assert(L->nci == 0); | 207 | lua_assert(L->nci == 0); |
209 | luaM_freearray(L, L->stack, L->stacksize); /* free stack array */ | 208 | luaM_freearray(L, L->stack, stacksize(L) + EXTRA_STACK); /* free stack */ |
210 | } | 209 | } |
211 | 210 | ||
212 | 211 | ||
@@ -256,7 +255,6 @@ static void preinit_thread (lua_State *L, global_State *g) { | |||
256 | L->stack = NULL; | 255 | L->stack = NULL; |
257 | L->ci = NULL; | 256 | L->ci = NULL; |
258 | L->nci = 0; | 257 | L->nci = 0; |
259 | L->stacksize = 0; | ||
260 | L->twups = L; /* thread has no upvalues */ | 258 | L->twups = L; /* thread has no upvalues */ |
261 | L->errorJmp = NULL; | 259 | L->errorJmp = NULL; |
262 | L->hook = NULL; | 260 | L->hook = NULL; |
@@ -127,12 +127,20 @@ struct lua_longjmp; /* defined in ldo.c */ | |||
127 | #endif | 127 | #endif |
128 | 128 | ||
129 | 129 | ||
130 | /* extra stack space to handle TM calls and some other extras */ | 130 | /* |
131 | ** Extra stack space to handle TM calls and some other extras. This | ||
132 | ** space is not included in 'stack_last'. It is used only to avoid stack | ||
133 | ** checks, either because the element will be promptly popped or because | ||
134 | ** there will be a stack check soon after the push. Function frames | ||
135 | ** never use this extra space, so it does not need to be kept clean. | ||
136 | */ | ||
131 | #define EXTRA_STACK 5 | 137 | #define EXTRA_STACK 5 |
132 | 138 | ||
133 | 139 | ||
134 | #define BASIC_STACK_SIZE (2*LUA_MINSTACK) | 140 | #define BASIC_STACK_SIZE (2*LUA_MINSTACK) |
135 | 141 | ||
142 | #define stacksize(th) cast_int((th)->stack_last - (th)->stack) | ||
143 | |||
136 | 144 | ||
137 | /* kinds of Garbage Collection */ | 145 | /* kinds of Garbage Collection */ |
138 | #define KGC_INC 0 /* incremental gc */ | 146 | #define KGC_INC 0 /* incremental gc */ |
@@ -270,7 +278,7 @@ struct lua_State { | |||
270 | StkId top; /* first free slot in the stack */ | 278 | StkId top; /* first free slot in the stack */ |
271 | global_State *l_G; | 279 | global_State *l_G; |
272 | CallInfo *ci; /* call info for current function */ | 280 | CallInfo *ci; /* call info for current function */ |
273 | StkId stack_last; /* last free slot in the stack */ | 281 | StkId stack_last; /* end of stack (last element + 1) */ |
274 | StkId stack; /* stack base */ | 282 | StkId stack; /* stack base */ |
275 | UpVal *openupval; /* list of open upvalues in this stack */ | 283 | UpVal *openupval; /* list of open upvalues in this stack */ |
276 | GCObject *gclist; | 284 | GCObject *gclist; |
@@ -281,7 +289,6 @@ struct lua_State { | |||
281 | ptrdiff_t errfunc; /* current error handling function (stack index) */ | 289 | ptrdiff_t errfunc; /* current error handling function (stack index) */ |
282 | l_uint32 nCcalls; /* number of nested (non-yieldable | C) calls */ | 290 | l_uint32 nCcalls; /* number of nested (non-yieldable | C) calls */ |
283 | int oldpc; /* last pc traced */ | 291 | int oldpc; /* last pc traced */ |
284 | int stacksize; | ||
285 | int basehookcount; | 292 | int basehookcount; |
286 | int hookcount; | 293 | int hookcount; |
287 | volatile l_signalT hookmask; | 294 | volatile l_signalT hookmask; |
@@ -430,17 +430,17 @@ static void checkstack (global_State *g, lua_State *L1) { | |||
430 | UpVal *uv; | 430 | UpVal *uv; |
431 | lua_assert(!isdead(g, L1)); | 431 | lua_assert(!isdead(g, L1)); |
432 | if (L1->stack == NULL) { /* incomplete thread? */ | 432 | if (L1->stack == NULL) { /* incomplete thread? */ |
433 | lua_assert(L1->stacksize == 0 && L1->openupval == NULL && | 433 | lua_assert(L1->openupval == NULL && L1->ci == NULL); |
434 | L1->ci == NULL); | ||
435 | return; | 434 | return; |
436 | } | 435 | } |
437 | for (uv = L1->openupval; uv != NULL; uv = uv->u.open.next) | 436 | for (uv = L1->openupval; uv != NULL; uv = uv->u.open.next) |
438 | lua_assert(upisopen(uv)); /* must be open */ | 437 | lua_assert(upisopen(uv)); /* must be open */ |
438 | lua_assert(L1->top <= L1->stack_last); | ||
439 | for (ci = L1->ci; ci != NULL; ci = ci->previous) { | 439 | for (ci = L1->ci; ci != NULL; ci = ci->previous) { |
440 | lua_assert(ci->top <= L1->stack_last); | 440 | lua_assert(ci->top <= L1->stack_last); |
441 | lua_assert(lua_checkpc(ci)); | 441 | lua_assert(lua_checkpc(ci)); |
442 | } | 442 | } |
443 | for (o = L1->stack; o < L1->stack_last + EXTRA_STACK; o++) | 443 | for (o = L1->stack; o < L1->stack_last; o++) |
444 | checkliveness(L1, s2v(o)); /* entire stack must have valid values */ | 444 | checkliveness(L1, s2v(o)); /* entire stack must have valid values */ |
445 | } | 445 | } |
446 | 446 | ||
@@ -969,7 +969,7 @@ static int hash_query (lua_State *L) { | |||
969 | static int stacklevel (lua_State *L) { | 969 | static int stacklevel (lua_State *L) { |
970 | unsigned long a = 0; | 970 | unsigned long a = 0; |
971 | lua_pushinteger(L, (L->top - L->stack)); | 971 | lua_pushinteger(L, (L->top - L->stack)); |
972 | lua_pushinteger(L, (L->stack_last - L->stack)); | 972 | lua_pushinteger(L, stacksize(L)); |
973 | lua_pushinteger(L, L->nCcalls); | 973 | lua_pushinteger(L, L->nCcalls); |
974 | lua_pushinteger(L, L->nci); | 974 | lua_pushinteger(L, L->nci); |
975 | lua_pushinteger(L, (unsigned long)&a); | 975 | lua_pushinteger(L, (unsigned long)&a); |
@@ -1151,7 +1151,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1151 | StkId ra; /* instruction's A register */ | 1151 | StkId ra; /* instruction's A register */ |
1152 | vmfetch(); | 1152 | vmfetch(); |
1153 | lua_assert(base == ci->func + 1); | 1153 | lua_assert(base == ci->func + 1); |
1154 | lua_assert(base <= L->top && L->top < L->stack + L->stacksize); | 1154 | lua_assert(base <= L->top && L->top < L->stack_last); |
1155 | /* invalidate top for instructions not expecting it */ | 1155 | /* invalidate top for instructions not expecting it */ |
1156 | lua_assert(isIT(i) || (cast_void(L->top = base), 1)); | 1156 | lua_assert(isIT(i) || (cast_void(L->top = base), 1)); |
1157 | vmdispatch (GET_OPCODE(i)) { | 1157 | vmdispatch (GET_OPCODE(i)) { |